diff options
author | 2015-09-13 08:41:44 +0200 | |
---|---|---|
committer | 2015-09-13 08:41:44 +0200 | |
commit | f88cefad27a1737c76e09d99c9fb43e173506081 (patch) | |
tree | 2d8167d03579c46e226471747eb4407bd00ed6fa /src/devices/sound/es5506.h | |
parent | e92ac9e0fa8e99869894bea00589bbb526be30aa (diff) |
Move all devices into separate part of src tree (nw)
Diffstat (limited to 'src/devices/sound/es5506.h')
-rw-r--r-- | src/devices/sound/es5506.h | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/src/devices/sound/es5506.h b/src/devices/sound/es5506.h new file mode 100644 index 00000000000..c434ec8b12e --- /dev/null +++ b/src/devices/sound/es5506.h @@ -0,0 +1,248 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/********************************************************************************************** + * + * Ensoniq ES5505/6 driver + * by Aaron Giles + * + **********************************************************************************************/ + +#pragma once + +#ifndef __ES5506_H__ +#define __ES5506_H__ + +#define MAKE_WAVS 0 + +#define MCFG_ES5506_REGION0(_region) \ + es5506_device::set_region0(*device, _region); + +#define MCFG_ES5506_REGION1(_region) \ + es5506_device::set_region1(*device, _region); + +#define MCFG_ES5506_REGION2(_region) \ + es5506_device::set_region2(*device, _region); + +#define MCFG_ES5506_REGION3(_region) \ + es5506_device::set_region3(*device, _region); + +#define MCFG_ES5506_CHANNELS(_chan) \ + es5506_device::set_channels(*device, _chan); + +#define MCFG_ES5506_IRQ_CB(_devcb) \ + devcb = &es5506_device::set_irq_callback(*device, DEVCB_##_devcb); + +#define MCFG_ES5506_READ_PORT_CB(_devcb) \ + devcb = &es5506_device::set_read_port_callback(*device, DEVCB_##_devcb); + + +#define MCFG_ES5505_REGION0(_region) \ + es5505_device::set_region0(*device, _region); + +#define MCFG_ES5505_REGION1(_region) \ + es5505_device::set_region1(*device, _region); + +#define MCFG_ES5505_CHANNELS(_chan) \ + es5505_device::set_channels(*device, _chan); + +#define MCFG_ES5505_IRQ_CB(_devcb) \ + devcb = &es5505_device::set_irq_callback(*device, DEVCB_##_devcb); + +#define MCFG_ES5505_READ_PORT_CB(_devcb) \ + devcb = &es5505_device::set_read_port_callback(*device, DEVCB_##_devcb); + + +/* struct describing a single playing voice */ + +struct es550x_voice +{ + es550x_voice(): + control(0), + freqcount(0), + start(0), + lvol(0), + end(0), + lvramp(0), + accum(0), + rvol(0), + rvramp(0), + ecount(0), + k2(0), + k2ramp(0), + k1(0), + k1ramp(0), + o4n1(0), + o3n1(0), + o3n2(0), + o2n1(0), + o2n2(0), + o1n1(0), + exbank(0), + index(0), + filtcount(0), + accum_mask(0) {} + + /* external state */ + UINT32 control; /* control register */ + UINT32 freqcount; /* frequency count register */ + UINT32 start; /* start register */ + UINT32 lvol; /* left volume register */ + UINT32 end; /* end register */ + UINT32 lvramp; /* left volume ramp register */ + UINT32 accum; /* accumulator register */ + UINT32 rvol; /* right volume register */ + UINT32 rvramp; /* right volume ramp register */ + UINT32 ecount; /* envelope count register */ + UINT32 k2; /* k2 register */ + UINT32 k2ramp; /* k2 ramp register */ + UINT32 k1; /* k1 register */ + UINT32 k1ramp; /* k1 ramp register */ + INT32 o4n1; /* filter storage O4(n-1) */ + INT32 o3n1; /* filter storage O3(n-1) */ + INT32 o3n2; /* filter storage O3(n-2) */ + INT32 o2n1; /* filter storage O2(n-1) */ + INT32 o2n2; /* filter storage O2(n-2) */ + INT32 o1n1; /* filter storage O1(n-1) */ + UINT32 exbank; /* external address bank */ + + /* internal state */ + UINT8 index; /* index of this voice */ + UINT8 filtcount; /* filter count */ + UINT32 accum_mask; +}; + +class es550x_device : public device_t, + public device_sound_interface +{ +public: + es550x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + ~es550x_device() {} + + static void set_region0(device_t &device, const char *region0) { downcast<es550x_device &>(device).m_region0 = region0; } + static void set_region1(device_t &device, const char *region1) { downcast<es550x_device &>(device).m_region1 = region1; } + static void set_region2(device_t &device, const char *region2) { downcast<es550x_device &>(device).m_region2 = region2; } + static void set_region3(device_t &device, const char *region3) { downcast<es550x_device &>(device).m_region3 = region3; } + static void set_channels(device_t &device, int channels) { downcast<es550x_device &>(device).m_channels = channels; } + template<class _Object> static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast<es550x_device &>(device).m_irq_cb.set_callback(object); } + template<class _Object> static devcb_base &set_read_port_callback(device_t &device, _Object object) { return downcast<es550x_device &>(device).m_read_port_cb.set_callback(object); } + + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_stop(); + virtual void device_reset(); + + // sound stream update overrides + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + + // internal state + sound_stream *m_stream; /* which stream are we using */ + int m_sample_rate; /* current sample rate */ + UINT16 * m_region_base[4]; /* pointer to the base of the region */ + UINT32 m_write_latch; /* currently accumulated data for write */ + UINT32 m_read_latch; /* currently accumulated data for read */ + UINT32 m_master_clock; /* master clock frequency */ + + UINT8 m_current_page; /* current register page */ + UINT8 m_active_voices; /* number of active voices */ + UINT8 m_mode; /* MODE register */ + UINT8 m_wst; /* W_ST register */ + UINT8 m_wend; /* W_END register */ + UINT8 m_lrend; /* LR_END register */ + UINT8 m_irqv; /* IRQV register */ + + es550x_voice m_voice[32]; /* the 32 voices */ + + INT32 * m_scratch; + + INT16 * m_ulaw_lookup; + UINT16 * m_volume_lookup; + + #if MAKE_WAVS + void * m_wavraw; /* raw waveform */ + #endif + + FILE *m_eslog; + + const char * m_region0; /* memory region where the sample ROM lives */ + const char * m_region1; /* memory region where the sample ROM lives */ + const char * m_region2; /* memory region where the sample ROM lives */ + const char * m_region3; /* memory region where the sample ROM lives */ + int m_channels; /* number of output channels: 1 .. 6 */ + devcb_write_line m_irq_cb; /* irq callback */ + devcb_read16 m_read_port_cb; /* input port read */ + + void update_irq_state(); + void update_internal_irq_state(); + void compute_tables(); + + void generate_dummy(es550x_voice *voice, UINT16 *base, INT32 *lbuffer, INT32 *rbuffer, int samples); + void generate_ulaw(es550x_voice *voice, UINT16 *base, INT32 *lbuffer, INT32 *rbuffer, int samples); + void generate_pcm(es550x_voice *voice, UINT16 *base, INT32 *lbuffer, INT32 *rbuffer, int samples); +}; + + +class es5506_device : public es550x_device +{ +public: + es5506_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + ~es5506_device() {} + + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); + void voice_bank_w(int voice, int bank); + +protected: + // device-level overrides + virtual void device_start(); + + // sound stream update overrides + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + + + void generate_samples(INT32 **outputs, int offset, int samples); + +private: + inline void reg_write_low(es550x_voice *voice, offs_t offset, UINT32 data); + inline void reg_write_high(es550x_voice *voice, offs_t offset, UINT32 data); + inline void reg_write_test(es550x_voice *voice, offs_t offset, UINT32 data); + inline UINT32 reg_read_low(es550x_voice *voice, offs_t offset); + inline UINT32 reg_read_high(es550x_voice *voice, offs_t offset); + inline UINT32 reg_read_test(es550x_voice *voice, offs_t offset); +}; + +extern const device_type ES5506; + + +class es5505_device : public es550x_device +{ +public: + es5505_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + DECLARE_READ16_MEMBER( read ); + DECLARE_WRITE16_MEMBER( write ); + void voice_bank_w(int voice, int bank); + +protected: + // device-level overrides + virtual void device_start(); + + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + + void generate_samples(INT32 **outputs, int offset, int samples); + +private: + // internal state + inline void reg_write_low(es550x_voice *voice, offs_t offset, UINT16 data, UINT16 mem_mask); + inline void reg_write_high(es550x_voice *voice, offs_t offset, UINT16 data, UINT16 mem_mask); + inline void reg_write_test(es550x_voice *voice, offs_t offset, UINT16 data, UINT16 mem_mask); + inline UINT16 reg_read_low(es550x_voice *voice, offs_t offset); + inline UINT16 reg_read_high(es550x_voice *voice, offs_t offset); + inline UINT16 reg_read_test(es550x_voice *voice, offs_t offset); +}; + +extern const device_type ES5505; + + +#endif /* __ES5506_H__ */ |