Previous 199869 Revisions Next

r19928 Saturday 29th December, 2012 at 19:21:00 UTC by Andrew Gardner
Modernize SNKWave sound device.  [Andrew Gardner]
[src/emu/sound]snkwave.c snkwave.h
[src/mame/drivers]snk.c

trunk/src/mame/drivers/snk.c
r19927r19928
13861386   AM_RANGE(0x0000, 0x3fff) AM_ROM
13871387   AM_RANGE(0x4000, 0x4000) AM_READ(marvins_soundlatch_r)
13881388   AM_RANGE(0x8000, 0x8001) AM_DEVWRITE_LEGACY("ay1", ay8910_address_data_w)
1389   AM_RANGE(0x8002, 0x8007) AM_DEVWRITE_LEGACY("wave", snkwave_w)
1389   AM_RANGE(0x8002, 0x8007) AM_DEVWRITE("wave", snkwave_device, snkwave_w)
13901390   AM_RANGE(0x8008, 0x8009) AM_DEVWRITE_LEGACY("ay2", ay8910_address_data_w)
13911391   AM_RANGE(0xa000, 0xa000) AM_READ(marvins_sound_nmi_ack_r)
13921392   AM_RANGE(0xe000, 0xe7ff) AM_RAM
r19927r19928
36613661   MCFG_SOUND_ADD("ay2", AY8910, 2000000)   /* verified on schematics */
36623662   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.35)
36633663
3664   MCFG_SOUND_ADD("wave", SNKWAVE, 8000000)   /* verified on schematics */
3664   MCFG_SNKWAVE_ADD("wave", 8000000)   /* verified on schematics */
36653665   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30)
36663666MACHINE_CONFIG_END
36673667
trunk/src/emu/sound/snkwave.c
r19927r19928
1010#include "snkwave.h"
1111
1212
13#define WAVEFORM_LENGTH 16
14
1513#define CLOCK_SHIFT 8
1614
1715
18struct snkwave_state
19{
20   /* global sound parameters */
21   sound_stream * stream;
22   int external_clock;
23   int sample_rate;
16const device_type SNKWAVE = &device_creator<snkwave_device>;
2417
25   /* data about the sound system */
26   UINT32 frequency;
27   UINT32 counter;
28   int waveform_position;
18//-------------------------------------------------
19//  snkwave_device - constructor
20//-------------------------------------------------
2921
30   /* decoded waveform table */
31   INT16 waveform[WAVEFORM_LENGTH];
32};
33
34INLINE snkwave_state *get_safe_token(device_t *device)
22snkwave_device::snkwave_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
23   : device_t(mconfig, SNKWAVE, "SNK Wave", tag, owner, clock),
24     device_sound_interface(mconfig, *this),
25     m_stream(NULL),
26     m_external_clock(0),
27     m_sample_rate(0),
28     m_frequency(0),
29     m_counter(0),
30     m_waveform_position(0)
3531{
36   assert(device != NULL);
37   assert(device->type() == SNKWAVE);
38   return (snkwave_state *)downcast<snkwave_device *>(device)->token();
3932}
4033
34//-------------------------------------------------
35//  device_start - device-specific startup
36//-------------------------------------------------
4137
42/* update the decoded waveform data */
43/* The programmable waveform consists of 8 3-bit nibbles.
44   The waveform goes to a 4-bit DAC and is played alternatingly forwards and
45   backwards.
46   When going forwards, bit 3 is 1. When going backwards, it's 0.
47   So the sequence 01234567 will play as
48   89ABCDEF76543210
49*/
50static void update_waveform(snkwave_state *chip, unsigned int offset, UINT8 data)
38void snkwave_device::device_start()
5139{
52   assert(offset < WAVEFORM_LENGTH/4);
40   assert(static_config() == 0);
5341
54   chip->waveform[offset * 2]     = ((data & 0x38) >> 3) << (12-CLOCK_SHIFT);
55   chip->waveform[offset * 2 + 1] = ((data & 0x07) >> 0) << (12-CLOCK_SHIFT);
56   chip->waveform[WAVEFORM_LENGTH-2 - offset * 2] = ~chip->waveform[offset * 2 + 1];
57   chip->waveform[WAVEFORM_LENGTH-1 - offset * 2] = ~chip->waveform[offset * 2];
42   /* adjust internal clock */
43   m_external_clock = clock();
44
45   /* adjust output clock */
46   m_sample_rate = m_external_clock >> CLOCK_SHIFT;
47
48   /* get stream channels */
49   m_stream = stream_alloc(0, 1, m_sample_rate);
50
51   /* reset all the voices */
52   m_frequency = 0;
53   m_counter = 0;
54   m_waveform_position = 0;
55
56   /* register with the save state system */
57   save_item(NAME(m_frequency));
58   save_item(NAME(m_counter));
59   save_item(NAME(m_waveform_position));
60   save_pointer(NAME(m_waveform), SNKWAVE_WAVEFORM_LENGTH);
5861}
5962
6063
61/* generate sound to the mix buffer */
62static STREAM_UPDATE( snkwave_update )
64//-------------------------------------------------
65//  sound_stream_update - handle update requests
66//  for our sound stream
67//-------------------------------------------------
68
69void snkwave_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
6370{
64   snkwave_state *chip = (snkwave_state *)param;
6571   stream_sample_t *buffer = outputs[0];
6672
6773   /* zap the contents of the buffer */
6874   memset(buffer, 0, samples * sizeof(*buffer));
6975
70   assert(chip->counter < 0x1000);
71   assert(chip->frequency < 0x1000);
76   assert(m_counter < 0x1000);
77   assert(m_frequency < 0x1000);
7278
7379   /* if no sound, we're done */
74   if (chip->frequency == 0xfff)
80   if (m_frequency == 0xfff)
7581      return;
7682
7783   /* generate sound into buffer while updating the counter */
r19927r19928
8389      loops = 1 << CLOCK_SHIFT;
8490      while (loops > 0)
8591      {
86         int steps = 0x1000 - chip->counter;
92         int steps = 0x1000 - m_counter;
8793
8894         if (steps <= loops)
8995         {
90            out += chip->waveform[chip->waveform_position] * steps;
91            chip->counter = chip->frequency;
92            chip->waveform_position = (chip->waveform_position + 1) & (WAVEFORM_LENGTH-1);
96            out += m_waveform[m_waveform_position] * steps;
97            m_counter = m_frequency;
98            m_waveform_position = (m_waveform_position + 1) & (SNKWAVE_WAVEFORM_LENGTH-1);
9399            loops -= steps;
94100         }
95101         else
96102         {
97            out += chip->waveform[chip->waveform_position] * loops;
98            chip->counter += loops;
103            out += m_waveform[m_waveform_position] * loops;
104            m_counter += loops;
99105            loops = 0;
100106         }
101107      }
r19927r19928
105111}
106112
107113
108static DEVICE_START( snkwave )
109{
110   snkwave_state *chip = get_safe_token(device);
111
112   assert(device->static_config() == 0);
113
114   /* adjust internal clock */
115   chip->external_clock = device->clock();
116
117   /* adjust output clock */
118   chip->sample_rate = chip->external_clock >> CLOCK_SHIFT;
119
120   /* get stream channels */
121   chip->stream = device->machine().sound().stream_alloc(*device, 0, 1, chip->sample_rate, chip, snkwave_update);
122
123   /* reset all the voices */
124   chip->frequency = 0;
125   chip->counter = 0;
126   chip->waveform_position = 0;
127
128   /* register with the save state system */
129   device->save_item(NAME(chip->frequency));
130   device->save_item(NAME(chip->counter));
131   device->save_item(NAME(chip->waveform_position));
132   device->save_pointer(NAME(chip->waveform), WAVEFORM_LENGTH);
133}
134
135
136/********************************************************************************/
137
138114/* SNK wave register map
139115    all registers are 6-bit
140116    0-1         frequency (12-bit)
141117    2-5         waveform (8 3-bit nibbles)
142118*/
143119
144WRITE8_DEVICE_HANDLER( snkwave_w )
120WRITE8_MEMBER( snkwave_device::snkwave_w )
145121{
146   snkwave_state *chip = get_safe_token(device);
122   m_stream->update();
147123
148   chip->stream->update();
149
150124   // all registers are 6-bit
151125   data &= 0x3f;
152126
153127   if (offset == 0)
154      chip->frequency = (chip->frequency & 0x03f) | (data << 6);
128      m_frequency = (m_frequency & 0x03f) | (data << 6);
155129   else if (offset == 1)
156      chip->frequency = (chip->frequency & 0xfc0) | data;
130      m_frequency = (m_frequency & 0xfc0) | data;
157131   else if (offset <= 5)
158      update_waveform(chip, offset - 2, data);
132      update_waveform(offset - 2, data);
159133}
160134
161const device_type SNKWAVE = &device_creator<snkwave_device>;
162135
163snkwave_device::snkwave_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
164   : device_t(mconfig, SNKWAVE, "SNK Wave", tag, owner, clock),
165     device_sound_interface(mconfig, *this)
136/* update the decoded waveform data */
137/* The programmable waveform consists of 8 3-bit nibbles.
138   The waveform goes to a 4-bit DAC and is played alternatingly forwards and
139   backwards.
140   When going forwards, bit 3 is 1. When going backwards, it's 0.
141   So the sequence 01234567 will play as
142   89ABCDEF76543210
143*/
144void snkwave_device::update_waveform(unsigned int offset, UINT8 data)
166145{
167   m_token = global_alloc_clear(snkwave_state);
168}
146   assert(offset < SNKWAVE_WAVEFORM_LENGTH/4);
169147
170//-------------------------------------------------
171//  device_config_complete - perform any
172//  operations now that the configuration is
173//  complete
174//-------------------------------------------------
175
176void snkwave_device::device_config_complete()
177{
148   m_waveform[offset * 2]     = ((data & 0x38) >> 3) << (12-CLOCK_SHIFT);
149   m_waveform[offset * 2 + 1] = ((data & 0x07) >> 0) << (12-CLOCK_SHIFT);
150   m_waveform[SNKWAVE_WAVEFORM_LENGTH-2 - offset * 2] = ~m_waveform[offset * 2 + 1];
151   m_waveform[SNKWAVE_WAVEFORM_LENGTH-1 - offset * 2] = ~m_waveform[offset * 2];
178152}
179153
180//-------------------------------------------------
181//  device_start - device-specific startup
182//-------------------------------------------------
183154
184void snkwave_device::device_start()
185{
186   DEVICE_START_NAME( snkwave )(this);
187}
188
189//-------------------------------------------------
190//  sound_stream_update - handle a stream update
191//-------------------------------------------------
192
193void snkwave_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
194{
195   // should never get here
196   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
197}
198
199
trunk/src/emu/sound/snkwave.h
r19927r19928
33#ifndef __SNKWAVE_H__
44#define __SNKWAVE_H__
55
6#include "devlegcy.h"
6#define SNKWAVE_WAVEFORM_LENGTH 16
77
8DECLARE_WRITE8_DEVICE_HANDLER( snkwave_w );
8//**************************************************************************
9//  INTERFACE CONFIGURATION MACROS
10//**************************************************************************
911
12#define MCFG_SNKWAVE_ADD(_tag, _clock) \
13   MCFG_DEVICE_ADD(_tag, SNKWAVE, _clock) \
14
15#define MCFG_SNKWAVE_REPLACE(_tag, _clock) \
16   MCFG_DEVICE_REPLACE(_tag, SNKWAVE, _clock) \
17
18
19
20//**************************************************************************
21//  TYPE DEFINITIONS
22//**************************************************************************
23
24
25// ======================> snkwave_device
26
1027class snkwave_device : public device_t,
11                                  public device_sound_interface
28                  public device_sound_interface
1229{
1330public:
1431   snkwave_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
15   ~snkwave_device() { global_free(m_token); }
32   ~snkwave_device() { }
1633
17   // access to legacy token
18   void *token() const { assert(m_token != NULL); return m_token; }
1934protected:
2035   // device-level overrides
21   virtual void device_config_complete();
2236   virtual void device_start();
2337
2438   // sound stream update overrides
2539   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
40
41public:
42   DECLARE_WRITE8_MEMBER( snkwave_w );
43
2644private:
27   // internal state
28   void *m_token;
45   void update_waveform(unsigned int offset, UINT8 data);
46
47private:
48   sound_stream *m_stream;
49   int m_external_clock;
50   int m_sample_rate;
51
52   // data about the sound system
53   UINT32 m_frequency;
54   UINT32 m_counter;
55   int m_waveform_position;
56
57   // decoded waveform table
58   INT16 m_waveform[SNKWAVE_WAVEFORM_LENGTH];
2959};
3060
3161extern const device_type SNKWAVE;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team