1 // license:GPL-2.0+
2 // copyright-holders:Couriersud
3 /***************************************************************************
4 
5     netlist.h
6 
7     Discrete netlist implementation.
8 
9 ****************************************************************************/
10 
11 #ifndef MAME_MACHINE_NETLIST_H
12 #define MAME_MACHINE_NETLIST_H
13 
14 #include <functional>
15 #include <deque>
16 
17 #include "../../lib/netlist/nltypes.h"
18 
19 #ifndef NETLIST_CREATE_CSV
20 #define NETLIST_CREATE_CSV (0)
21 #endif
22 
23 class netlist_mame_stream_output_device;
24 class nld_sound_in;
25 
26 namespace netlist {
27 	class setup_t;
28 	class netlist_t;
29 	class netlist_state_t;
30 	class nlparse_t;
31 	template <typename T>
32 	class param_num_t;
33 	class param_ptr_t;
34 }
35 
36 
37 // MAME specific configuration
38 
39 #define NETLIST_LOGIC_PORT_CHANGED(_base, _tag)                                     \
40 	PORT_CHANGED_MEMBER(_base ":" _tag, netlist_mame_logic_input_device, input_changed, 0)
41 
42 #define NETLIST_INT_PORT_CHANGED(_base, _tag)                                     \
43 	PORT_CHANGED_MEMBER(_base ":" _tag, netlist_mame_logic_input_device, input_changed, 0)
44 
45 #define NETLIST_ANALOG_PORT_CHANGED(_base, _tag)                                    \
46 	PORT_CHANGED_MEMBER(_base ":" _tag, netlist_mame_analog_input_device, input_changed, 0)
47 
48 /* This macro can only be called from device member */
49 
50 #define MEMREGION_SOURCE(_name) \
51 		netlist_mame_device::register_memregion_source(setup, *this,  _name);
52 
53 #define NETDEV_ANALOG_CALLBACK_MEMBER(_name) \
54 	void _name(const double data, const attotime &time)
55 
56 #define NETDEV_LOGIC_CALLBACK_MEMBER(_name) \
57 	void _name(const int data, const attotime &time)
58 
59 
60 
61 // ----------------------------------------------------------------------------------------
62 // netlist_mame_device
63 // ----------------------------------------------------------------------------------------
64 
65 class netlist_mame_device : public device_t
66 {
67 public:
68 	class netlist_mame_t;
69 	class netlist_mame_callbacks_t;
70 
71 	using func_type = std::function<void(netlist::nlparse_t &)>;
72 
73 	// construction/destruction
74 	netlist_mame_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
75 
76 	virtual ~netlist_mame_device();
77 
set_setup_func(func_type && func)78 	void set_setup_func(func_type &&func) noexcept { m_setup_func = std::move(func); }
79 
80 	netlist::setup_t &setup();
netlist()81 	netlist_mame_t &netlist() noexcept { return *m_netlist; }
82 
83 	static void register_memregion_source(netlist::nlparse_t &parser, device_t &dev, const char *name);
84 
85 protected:
86 
87 	netlist_mame_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
88 
89 	// Custom to netlist ...
nl_register_devices(netlist::nlparse_t & parser)90 	virtual void nl_register_devices(netlist::nlparse_t &parser) const { }
91 
92 	// device_t overrides
93 	virtual void device_config_complete() override;
94 	virtual void device_validity_check(validity_checker &valid) const override;
95 	virtual void device_start() override;
96 	virtual void device_stop() override;
97 	virtual void device_reset() override;
98 	virtual void device_post_load() override;
99 	virtual void device_pre_save() override;
100 	//virtual void device_clock_changed() override;
101 
102 	void device_start_common();
103 	void save_state();
104 
105 	std::unique_ptr<netlist::netlist_state_t> base_validity_check(validity_checker &valid) const;
106 
107 private:
108 
109 	void common_dev_start(netlist::netlist_state_t *lnetlist) const;
110 
111 	std::unique_ptr<netlist_mame_t> m_netlist;
112 
113 	func_type m_setup_func;
114 	bool m_device_reset_called;
115 
116 #if NETLIST_CREATE_CSV
117 	static constexpr int MAX_BUFFER_ENTRIES = 1000;
118 
119 public:
120 	void log_add(char const* param, double value, bool isfloat);
121 	void log_flush(int count = MAX_BUFFER_ENTRIES);
122 
123 private:
124 	struct buffer_entry
125 	{
126 		attotime time;
127 		bool isfloat;
128 		double value;
129 		char const *string;
130 	};
131 	std::deque<buffer_entry> m_buffer;
132 	FILE* m_csv_file = nullptr;
133 #endif
134 };
135 
136 class netlist_mame_cpu_device : public netlist_mame_device,
137 								public device_execute_interface,
138 								public device_state_interface,
139 								public device_disasm_interface,
140 								public device_memory_interface
141 {
142 public:
143 	static constexpr const unsigned MDIV_SHIFT = 16;
144 
145 	// construction/destruction
146 	netlist_mame_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
147 
~netlist_mame_cpu_device()148 	~netlist_mame_cpu_device()
149 	{
150 
151 	}
152 
genPC()153 	offs_t genPC() const { return m_genPC; }
154 
set_source(void (* setup_func)(netlist::nlparse_t &))155 	netlist_mame_cpu_device & set_source(void (*setup_func)(netlist::nlparse_t &))
156 	{
157 		set_setup_func(func_type(setup_func));
158 		return *this;
159 	}
160 
161 	template <typename T, typename F>
set_source(T * obj,F && f)162 	netlist_mame_cpu_device & set_source(T *obj, F && f)
163 	{
164 		set_setup_func(std::move(std::bind(std::forward<F>(f), obj, std::placeholders::_1)));
165 		return *this;
166 	}
167 
168 	void update_icount(netlist::netlist_time_ext time) noexcept;
169 	void check_mame_abort_slice() noexcept;
170 
nltime_ext_from_clocks(unsigned c)171 	netlist::netlist_time_ext nltime_ext_from_clocks(unsigned c) const noexcept
172 	{
173 		return (m_div * c).shr(MDIV_SHIFT);
174 	}
175 
nltime_from_clocks(unsigned c)176 	netlist::netlist_time nltime_from_clocks(unsigned c) const noexcept
177 	{
178 		return static_cast<netlist::netlist_time>((m_div * c).shr(MDIV_SHIFT));
179 	}
180 
181 protected:
182 	// netlist_mame_device
183 	virtual void nl_register_devices(netlist::nlparse_t &parser) const override;
184 
185 	// device_t overrides
186 	virtual void device_start() override;
187 	virtual void device_clock_changed() override;
188 
189 	// device_execute_interface overrides
190 	virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override;
191 	virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override;
192 
193 	ATTR_HOT virtual void execute_run() override;
194 
195 	// device_disasm_interface overrides
196 	virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
197 
198 	// device_memory_interface overrides
199 	virtual space_config_vector memory_space_config() const override;
200 
201 	//  device_state_interface overrides
202 	virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
203 
204 	address_space_config m_program_config;
205 
206 private:
207 	int m_icount;
208 	netlist::netlist_time_ext    m_div;
209 	netlist::netlist_time_ext    m_rem;
210 	netlist::netlist_time_ext    m_old;
211 	offs_t m_genPC;
212 };
213 
214 // ----------------------------------------------------------------------------------------
215 // netlist_mame_cpu_device
216 // ----------------------------------------------------------------------------------------
217 
218 class netlist_disassembler : public util::disasm_interface
219 {
220 public:
221 	netlist_disassembler(netlist_mame_cpu_device *dev);
222 	virtual ~netlist_disassembler() = default;
223 
224 	virtual u32 opcode_alignment() const override;
225 	virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
226 
227 private:
228 	netlist_mame_cpu_device *m_dev;
229 };
230 
231 // ----------------------------------------------------------------------------------------
232 // netlist_mame_sound_input_buffer
233 // ----------------------------------------------------------------------------------------
234 
235 class netlist_mame_sound_input_buffer : public read_stream_view
236 {
237 public:
netlist_mame_sound_input_buffer()238 	netlist_mame_sound_input_buffer() :
239 		read_stream_view() { }
240 
netlist_mame_sound_input_buffer(read_stream_view const & src)241 	netlist_mame_sound_input_buffer(read_stream_view const &src) :
242 		read_stream_view(src) { }
243 
244 	stream_buffer::sample_t operator[](std::size_t index) { return get(index); }
245 };
246 
247 // ----------------------------------------------------------------------------------------
248 // netlist_mame_sound_device
249 // ----------------------------------------------------------------------------------------
250 
251 class netlist_mame_sound_device : public netlist_mame_device,
252 								  public device_sound_interface
253 {
254 public:
255 	// construction/destruction
256 	netlist_mame_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
257 
set_source(void (* setup_func)(netlist::nlparse_t &))258 	netlist_mame_sound_device & set_source(void (*setup_func)(netlist::nlparse_t &))
259 	{
260 		set_setup_func(func_type(setup_func));
261 		return *this;
262 	}
263 
264 	template <typename T, typename F>
set_source(T * obj,F && f)265 	netlist_mame_sound_device & set_source(T *obj, F && f)
266 	{
267 		set_setup_func(std::move(std::bind(std::forward<F>(f), obj, std::placeholders::_1)));
268 		return *this;
269 	}
270 
271 
get_stream()272 	inline sound_stream *get_stream() { return m_stream; }
273 	void update_to_current_time();
274 
275 	void register_stream_output(int channel, netlist_mame_stream_output_device *so);
276 
277 protected:
278 
279 	// netlist_mame_device
280 	virtual void nl_register_devices(netlist::nlparse_t &parser) const override;
281 
282 	// device_t overrides
283 	virtual void device_start() override;
284 	// device_sound_interface overrides
285 	virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
286 	virtual void device_validity_check(validity_checker &valid) const override;
287 	//virtual void device_reset() override;
288 
289 private:
290 	std::map<int, netlist_mame_stream_output_device *> m_out;
291 	std::map<std::size_t, nld_sound_in *> m_in;
292 	std::vector<netlist_mame_sound_input_buffer> m_inbuffer;
293 	sound_stream *m_stream;
294 	attotime m_cur_time;
295 	uint32_t m_sound_clock;
296 	attotime m_attotime_per_clock;
297 	attotime m_last_update_to_current_time;
298 };
299 
300 // ----------------------------------------------------------------------------------------
301 // netlist_mame_sub_interface
302 // ----------------------------------------------------------------------------------------
303 
304 class netlist_mame_sub_interface
305 {
306 public:
307 	// construction/destruction
netlist_mame_sub_interface(device_t & owner)308 	netlist_mame_sub_interface(device_t &owner)
309 		: m_offset(0.0), m_mult(1.0)
310 		, m_owner(dynamic_cast<netlist_mame_device *>(&owner))
311 		, m_sound(dynamic_cast<netlist_mame_sound_device *>(&owner))
312 		, m_cpu(dynamic_cast<netlist_mame_cpu_device *>(&owner))
313 	{
314 	}
315 
~netlist_mame_sub_interface()316 	virtual ~netlist_mame_sub_interface()
317 	{
318 	}
319 
custom_netlist_additions(netlist::nlparse_t & parser)320 	virtual void custom_netlist_additions(netlist::nlparse_t &parser) { }
pre_parse_action(netlist::nlparse_t & parser)321 	virtual void pre_parse_action(netlist::nlparse_t &parser) { }
validity_helper(validity_checker & valid,netlist::netlist_state_t & nlstate)322 	virtual void validity_helper(validity_checker &valid,
323 		netlist::netlist_state_t &nlstate) const { }
324 
nl_owner()325 	inline netlist_mame_device &nl_owner() const { return *m_owner; }
326 
update_to_current_time()327 	inline void update_to_current_time()
328 	{
329 		if (m_sound != nullptr)
330 		{
331 			m_sound->update_to_current_time();
332 		}
333 	}
334 
335 	void set_mult_offset(const double mult, const double offset);
336 
sound()337 	netlist_mame_sound_device *sound() { return m_sound;}
cpu()338 	netlist_mame_cpu_device   *cpu()   { return m_cpu;}
339 
340 protected:
341 	double m_offset;
342 	double m_mult;
343 
344 private:
345 	netlist_mame_device       *const m_owner;
346 	netlist_mame_sound_device *const m_sound;
347 	netlist_mame_cpu_device   *const m_cpu;
348 };
349 
350 // ----------------------------------------------------------------------------------------
351 // netlist_mame_analog_input_device
352 // ----------------------------------------------------------------------------------------
353 
354 class netlist_mame_analog_input_device : public device_t, public netlist_mame_sub_interface
355 {
356 public:
357 
358 	// construction/destruction
359 	netlist_mame_analog_input_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *param_name);
360 
361 	netlist_mame_analog_input_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
362 
set_name(const char * param_name)363 	void set_name(const char *param_name) { m_param_name = param_name; }
364 
365 	void write(const double val);
366 
DECLARE_INPUT_CHANGED_MEMBER(input_changed)367 	inline DECLARE_INPUT_CHANGED_MEMBER(input_changed)
368 	{
369 		if (m_auto_port)
370 			write((double(newval) - double(field.minval())) / double(field.maxval() - field.minval()));
371 		else
372 			write(newval);
373 	}
DECLARE_WRITE_LINE_MEMBER(write_line)374 	inline DECLARE_WRITE_LINE_MEMBER(write_line)       { write(state);  }
write8(uint8_t data)375 	inline void write8(uint8_t data)               { write(data);   }
write16(uint16_t data)376 	inline void write16(uint16_t data)             { write(data);   }
write32(uint32_t data)377 	inline void write32(uint32_t data)             { write(data);   }
write64(uint64_t data)378 	inline void write64(uint64_t data)             { write(data);   }
379 
380 	virtual void validity_helper(validity_checker &valid,
381 		netlist::netlist_state_t &nlstate) const override;
382 protected:
383 	// device-level overrides
384 	virtual void device_start() override;
385 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
386 
387 private:
388 	netlist::param_num_t<netlist::nl_fptype> *m_param;
389 	bool   m_auto_port;
390 	const char *m_param_name;
391 	double m_value_for_device_timer;
392 };
393 
394 // ----------------------------------------------------------------------------------------
395 // netlist_mame_analog_output_device
396 // ----------------------------------------------------------------------------------------
397 
398 class netlist_mame_analog_output_device : public device_t, public netlist_mame_sub_interface
399 {
400 public:
401 	typedef device_delegate<void (const double, const attotime &)> output_delegate;
402 
403 	// construction/destruction
404 	netlist_mame_analog_output_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
405 
406 	template <typename... T>
set_params(const char * in_name,T &&...args)407 	void set_params(const char *in_name, T &&... args)
408 	{
409 		m_in = in_name;
410 		m_delegate.set(std::forward<T>(args)...);
411 	}
412 
413 protected:
414 	// device-level overrides
415 	virtual void device_start() override;
416 	virtual void pre_parse_action(netlist::nlparse_t &parser) override;
417 	virtual void custom_netlist_additions(netlist::nlparse_t &parser) override;
418 
419 private:
420 	const char *m_in;
421 	output_delegate m_delegate;
422 };
423 
424 // ----------------------------------------------------------------------------------------
425 // netlist_mame_logic_output_device
426 // ----------------------------------------------------------------------------------------
427 
428 class netlist_mame_logic_output_device : public device_t, public netlist_mame_sub_interface
429 {
430 public:
431 	typedef device_delegate<void(const int, const attotime &)> output_delegate;
432 
433 	// construction/destruction
434 	netlist_mame_logic_output_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
435 
set_params(const char * in_name,T &&...args)436 	template <typename... T> void set_params(const char *in_name, T &&... args)
437 	{
438 		m_in = in_name;
439 		m_delegate.set(std::forward<T>(args)...);
440 	}
441 
442 protected:
443 	// device-level overrides
444 	virtual void device_start() override;
445 	virtual void pre_parse_action(netlist::nlparse_t &parser) override;
446 	virtual void custom_netlist_additions(netlist::nlparse_t &parser) override;
447 
448 private:
449 	const char *m_in;
450 	output_delegate m_delegate;
451 };
452 
453 // ----------------------------------------------------------------------------------------
454 // netlist_mame_int_input_device
455 // ----------------------------------------------------------------------------------------
456 
457 class netlist_mame_int_input_device : public device_t, public netlist_mame_sub_interface
458 {
459 public:
460 	// construction/destruction
netlist_mame_int_input_device(const machine_config & mconfig,const char * tag,device_t * owner,const char * param_name,const uint32_t shift,const uint32_t mask)461 	netlist_mame_int_input_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *param_name, const uint32_t shift,
462 		const uint32_t mask)
463 		: netlist_mame_int_input_device(mconfig, tag, owner, (uint32_t)0)
464 	{
465 		set_params(param_name, mask, shift);
466 	}
467 	netlist_mame_int_input_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
468 
469 	void set_params(const char *param_name, const uint32_t mask, const uint32_t shift);
470 
471 	void write(const uint32_t val);
472 
DECLARE_INPUT_CHANGED_MEMBER(input_changed)473 	inline DECLARE_INPUT_CHANGED_MEMBER(input_changed) { write(newval); }
DECLARE_WRITE_LINE_MEMBER(write_line)474 	DECLARE_WRITE_LINE_MEMBER(write_line)       { write(state);  }
write8(uint8_t data)475 	void write8(uint8_t data)               { write(data);   }
write16(uint16_t data)476 	void write16(uint16_t data)             { write(data);   }
write32(uint32_t data)477 	void write32(uint32_t data)             { write(data);   }
write64(uint64_t data)478 	void write64(uint64_t data)             { write(data);   }
479 
480 	virtual void validity_helper(validity_checker &valid, netlist::netlist_state_t &nlstate) const override;
481 
482 protected:
483 	// device-level overrides
484 	virtual void device_start() override;
485 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
486 
487 private:
488 	netlist::param_num_t<int> *m_param;
489 	uint32_t m_mask;
490 	uint32_t m_shift;
491 	const char *m_param_name;
492 };
493 
494 
495 // ----------------------------------------------------------------------------------------
496 // netlist_mame_logic_input_device
497 // ----------------------------------------------------------------------------------------
498 
499 class netlist_mame_logic_input_device : public device_t, public netlist_mame_sub_interface
500 {
501 public:
502 	// construction/destruction
netlist_mame_logic_input_device(const machine_config & mconfig,const char * tag,device_t * owner,const char * param_name,const uint32_t shift)503 	netlist_mame_logic_input_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *param_name, const uint32_t shift)
504 		: netlist_mame_logic_input_device(mconfig, tag, owner, (uint32_t)0)
505 	{
506 		set_params(param_name, shift);
507 	}
508 	netlist_mame_logic_input_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
509 
510 	void set_params(const char *param_name, const uint32_t shift);
511 
512 	void write(const uint32_t val);
513 
DECLARE_INPUT_CHANGED_MEMBER(input_changed)514 	inline DECLARE_INPUT_CHANGED_MEMBER(input_changed) { write(newval); }
DECLARE_WRITE_LINE_MEMBER(write_line)515 	DECLARE_WRITE_LINE_MEMBER(write_line)       { write(state);  }
write8(uint8_t data)516 	void write8(uint8_t data)               { write(data);   }
write16(uint16_t data)517 	void write16(uint16_t data)             { write(data);   }
write32(uint32_t data)518 	void write32(uint32_t data)             { write(data);   }
write64(uint64_t data)519 	void write64(uint64_t data)             { write(data);   }
520 
521 	virtual void validity_helper(validity_checker &valid, netlist::netlist_state_t &nlstate) const override;
522 
523 protected:
524 	// device-level overrides
525 	virtual void device_start() override;
526 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
527 
528 private:
529 	netlist::param_num_t<bool> *m_param;
530 	uint32_t m_shift;
531 	const char *m_param_name;
532 };
533 
534 // ----------------------------------------------------------------------------------------
535 // netlist_mame_ram_pointer_device
536 // ----------------------------------------------------------------------------------------
537 
538 class netlist_mame_ram_pointer_device : public device_t, public netlist_mame_sub_interface
539 {
540 public:
541 	// construction/destruction
542 	netlist_mame_ram_pointer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
543 	netlist_mame_ram_pointer_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *pname);
544 
ptr()545 	uint8_t* ptr() const { return m_data; }
546 
547 	void set_params(const char *param_name);
548 
549 	virtual void validity_helper(validity_checker &valid, netlist::netlist_state_t &nlstate) const override;
550 
551 protected:
552 	// device-level overrides
553 	virtual void device_start() override;
554 	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
555 
556 private:
557 	netlist::param_ptr_t *m_param;
558 	const char *m_param_name;
559 	uint8_t* m_data;
560 };
561 
562 // ----------------------------------------------------------------------------------------
563 // netlist_mame_stream_input_device
564 // ----------------------------------------------------------------------------------------
565 
566 class netlist_mame_stream_input_device : public device_t, public netlist_mame_sub_interface
567 {
568 public:
569 	// construction/destruction
netlist_mame_stream_input_device(const machine_config & mconfig,const char * tag,device_t * owner,int channel,const char * param_name)570 	netlist_mame_stream_input_device(const machine_config &mconfig, const char *tag, device_t *owner, int channel, const char *param_name)
571 		: netlist_mame_stream_input_device(mconfig, tag, owner, (uint32_t)0)
572 	{
573 		set_params(channel, param_name);
574 	}
575 	netlist_mame_stream_input_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
576 
577 	void set_params(int channel, const char *param_name);
578 
579 protected:
580 	// device-level overrides
581 	virtual void device_start() override;
582 	virtual void custom_netlist_additions(netlist::nlparse_t &parser) override;
583 private:
584 	uint32_t m_channel;
585 	const char *m_param_name;
586 };
587 
588 // ----------------------------------------------------------------------------------------
589 // netlist_mame_stream_output_device
590 // ----------------------------------------------------------------------------------------
591 
592 class netlist_mame_stream_output_device : public device_t, public netlist_mame_sub_interface
593 {
594 public:
595 	// construction/destruction
netlist_mame_stream_output_device(const machine_config & mconfig,const char * tag,device_t * owner,int channel,const char * out_name)596 	netlist_mame_stream_output_device(const machine_config &mconfig, const char *tag, device_t *owner, int channel, const char *out_name)
597 		: netlist_mame_stream_output_device(mconfig, tag, owner, (uint32_t)0)
598 	{
599 		set_params(channel, out_name);
600 	}
601 	netlist_mame_stream_output_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
602 
603 	void set_params(int channel, const char *out_name);
604 
605 	void process(netlist::netlist_time_ext tim, netlist::nl_fptype val);
606 
buffer_reset(const netlist::netlist_time_ext & upto)607 	void buffer_reset(const netlist::netlist_time_ext &upto)
608 	{
609 		m_last_buffer_time = upto;
610 		m_buffer.clear();
611 	}
612 
613 	void sound_update_fill(write_stream_view &target);
614 
set_sample_time(netlist::netlist_time t)615 	void set_sample_time(netlist::netlist_time t) { m_sample_time = t; }
616 
617 protected:
618 	// device-level overrides
619 	virtual void device_start() override;
620 	virtual void device_reset() override;
621 	virtual void custom_netlist_additions(netlist::nlparse_t &parser) override;
622 	virtual void pre_parse_action(netlist::nlparse_t &parser) override;
623 
624 private:
625 	uint32_t                     m_channel;
626 	const char *                 m_out_name;
627 
628 	std::vector<stream_buffer::sample_t> m_buffer;
629 	double                       m_cur;
630 
631 	netlist::netlist_time        m_sample_time;
632 	netlist::netlist_time_ext    m_last_buffer_time;
633 };
634 
635 
636 // device type definition
637 DECLARE_DEVICE_TYPE(NETLIST_CORE,          netlist_mame_device)
638 DECLARE_DEVICE_TYPE(NETLIST_CPU,           netlist_mame_cpu_device)
639 DECLARE_DEVICE_TYPE(NETLIST_SOUND,         netlist_mame_sound_device)
640 DECLARE_DEVICE_TYPE(NETLIST_ANALOG_INPUT,  netlist_mame_analog_input_device)
641 DECLARE_DEVICE_TYPE(NETLIST_LOGIC_INPUT,   netlist_mame_logic_input_device)
642 DECLARE_DEVICE_TYPE(NETLIST_INT_INPUT,     netlist_mame_int_input_device)
643 DECLARE_DEVICE_TYPE(NETLIST_RAM_POINTER,   netlist_mame_ram_pointer_device)
644 DECLARE_DEVICE_TYPE(NETLIST_LOGIC_OUTPUT,  netlist_mame_logic_output_device)
645 DECLARE_DEVICE_TYPE(NETLIST_ANALOG_OUTPUT, netlist_mame_analog_output_device)
646 DECLARE_DEVICE_TYPE(NETLIST_STREAM_INPUT,  netlist_mame_stream_input_device)
647 DECLARE_DEVICE_TYPE(NETLIST_STREAM_OUTPUT, netlist_mame_stream_output_device)
648 
649 #endif // MAME_MACHINE_NETLIST_H
650