Previous 199869 Revisions Next

r19925 Saturday 29th December, 2012 at 17:08:30 UTC by Andrew Gardner
Modernize the NiLe sound device. [Andrew Gardner]
[src/emu/sound]nile.c nile.h
[src/mame/drivers]srmp6.c

trunk/src/mame/drivers/srmp6.c
r19924r19925
563563   //AM_RANGE(0x5fff00, 0x5fffff) AM_WRITE_LEGACY(dma_w) AM_SHARE("dmaram")
564564
565565   AM_RANGE(0x4c0000, 0x4c006f) AM_READWRITE(video_regs_r, video_regs_w) AM_SHARE("video_regs")   // ? gfx regs ST-0026 NiLe
566   AM_RANGE(0x4e0000, 0x4e00ff) AM_DEVREADWRITE_LEGACY("nile", nile_snd_r, nile_snd_w)
567   AM_RANGE(0x4e0100, 0x4e0101) AM_DEVREADWRITE_LEGACY("nile", nile_sndctrl_r, nile_sndctrl_w)
566   AM_RANGE(0x4e0000, 0x4e00ff) AM_DEVREADWRITE("nile", nile_device, nile_snd_r, nile_snd_w)
567   AM_RANGE(0x4e0100, 0x4e0101) AM_DEVREADWRITE("nile", nile_device, nile_sndctrl_r, nile_sndctrl_w)
568568   //AM_RANGE(0x4e0110, 0x4e0111) AM_NOP // ? accessed once ($268dc, written $b.w)
569569   //AM_RANGE(0x5fff00, 0x5fff1f) AM_RAM // ? see routine $5ca8, video_regs related ???
570570
r19924r19925
689689   /* sound hardware */
690690   MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
691691
692   MCFG_SOUND_ADD("nile", NILE, 0)
692   MCFG_NILE_ADD("nile", 0)
693693   MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
694694   MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
695695MACHINE_CONFIG_END
trunk/src/emu/sound/nile.c
r19924r19925
2727#include "emu.h"
2828#include "nile.h"
2929
30#define NILE_VOICES 8
31
3230enum
3331{
3432   NILE_REG_UNK0=0,
r19924r19925
5048};
5149
5250
51const device_type NILE = &device_creator<nile_device>;
5352
54struct nile_state
53nile_device::nile_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
54   : device_t(mconfig, NILE, "NiLe", tag, owner, clock),
55     device_sound_interface(mconfig, *this),
56     m_stream(NULL),
57     m_sound_ram(NULL),
58     m_ctrl(0)
5559{
56   sound_stream * stream;
57   UINT8 *sound_ram;
58   UINT16 sound_regs[0x80];
59   int vpos[NILE_VOICES], frac[NILE_VOICES], lponce[NILE_VOICES];
60   UINT16 ctrl;
61};
62
63INLINE nile_state *get_safe_token(device_t *device)
64{
65   assert(device != NULL);
66   assert(device->type() == NILE);
67   return (nile_state *)downcast<nile_device *>(device)->token();
6860}
6961
7062
71WRITE16_DEVICE_HANDLER( nile_sndctrl_w )
72{
73   nile_state *info = get_safe_token(device);
74   UINT16 ctrl=info->ctrl;
63//-------------------------------------------------
64//  device_start - device-specific startup
65//-------------------------------------------------
7566
76   info->stream->update();
77
78   COMBINE_DATA(&info->ctrl);
79
80//  printf("CTRL: %04x -> %04x (PC=%x)\n", ctrl, info->ctrl, space.device().safe_pc());
81
82   ctrl^=info->ctrl;
83}
84
85READ16_DEVICE_HANDLER( nile_sndctrl_r )
67void nile_device::device_start()
8668{
87   nile_state *info = get_safe_token(device);
88
89   info->stream->update();
90
91   return info->ctrl;
69   m_sound_ram = *region();
70   m_stream = stream_alloc(0, 2, 44100);
9271}
9372
94READ16_DEVICE_HANDLER( nile_snd_r )
95{
96   nile_state *info = get_safe_token(device);
97   int reg=offset&0xf;
9873
99   info->stream->update();
74//-------------------------------------------------
75//  sound_stream_update - handle update requests
76//  for our sound stream
77//-------------------------------------------------
10078
101   if(reg==2 || reg==3)
102   {
103      int slot=offset/16;
104      int sptr = ((info->sound_regs[slot*16+3]<<16)|info->sound_regs[slot*16+2])+info->vpos[slot];
105
106      if(reg==2)
107      {
108         return sptr&0xffff;
109      }
110      else
111      {
112         return sptr>>16;
113      }
114   }
115   return info->sound_regs[offset];
116}
117
118WRITE16_DEVICE_HANDLER( nile_snd_w )
79void nile_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
11980{
120   nile_state *info = get_safe_token(device);
121   int v, r;
122
123   info->stream->update();
124
125   COMBINE_DATA(&info->sound_regs[offset]);
126
127   v = offset / 16;
128   r = offset % 16;
129
130   if ((r == 2) || (r == 3))
131   {
132      info->vpos[v] = info->frac[v] = info->lponce[v] = 0;
133   }
134
135   //printf("v%02d: %04x to reg %02d (PC=%x)\n", v, info->sound_regs[offset], r, space.device().safe_pc());
136}
137
138static STREAM_UPDATE( nile_update )
139{
140   nile_state *info = (nile_state *)param;
141   UINT8 *sound_ram = info->sound_ram;
81   UINT8 *sound_ram = m_sound_ram;
14282   int v, i, snum;
14383   UINT16 *slot;
14484   INT32 mix[48000*2];
r19924r19925
15292
15393   for (v = 0; v < NILE_VOICES; v++)
15494   {
155      slot = &info->sound_regs[v * 16];
95      slot = &m_sound_regs[v * 16];
15696
157      if (info->ctrl&(1<<v))
97      if (m_ctrl&(1<<v))
15898      {
15999         mixp = &mix[0];
160100
r19924r19925
167107
168108         for (snum = 0; snum < samples; snum++)
169109         {
170            sample = sound_ram[sptr + info->vpos[v]]<<8;
110            sample = sound_ram[sptr + m_vpos[v]]<<8;
171111
172112            *mixp++ += (sample * (INT32)slot[NILE_REG_VOL_R]) >> 16;
173113            *mixp++ += (sample * (INT32)slot[NILE_REG_VOL_L]) >> 16;
174114
175            info->frac[v] += freq;
176            info->vpos[v] += info->frac[v]>>16;
177            info->frac[v] &= 0xffff;
115            m_frac[v] += freq;
116            m_vpos[v] += m_frac[v]>>16;
117            m_frac[v] &= 0xffff;
178118
179119            // stop if we're at the end
180            if (info->lponce[v])
120            if (m_lponce[v])
181121            {
182122               // we've looped once, check loop end rather than sample end
183               if ((info->vpos[v] + sptr) >= leptr)
123               if ((m_vpos[v] + sptr) >= leptr)
184124               {
185                  info->vpos[v] = (lsptr - sptr);
125                  m_vpos[v] = (lsptr - sptr);
186126               }
187127            }
188128            else
189129            {
190130               // not looped yet, check sample end
191               if ((info->vpos[v] + sptr) >= eptr)
131               if ((m_vpos[v] + sptr) >= eptr)
192132               {
193133                  // code at 11d8c:
194134                  // if bit 2 (0x4) is set, check if loop start = loop end.
r19924r19925
197137                  // the loop start/end registers in the NiLe.
198138                  if ((slot[NILE_REG_FLAGS] & 0x5) == 0x5)
199139                  {
200                     info->vpos[v] = (lsptr - sptr);
201                     info->lponce[v] = 1;
140                     m_vpos[v] = (lsptr - sptr);
141                     m_lponce[v] = 1;
202142                  }
203143                  else
204144                  {
205                     info->ctrl &= ~(1<<v);
206                     info->vpos[v] = (eptr - sptr);
207                     info->frac[v] = 0;
145                     m_ctrl &= ~(1<<v);
146                     m_vpos[v] = (eptr - sptr);
147                     m_frac[v] = 0;
208148                  }
209149
210150               }
r19924r19925
220160   }
221161}
222162
223static DEVICE_START( nile )
163
164WRITE16_MEMBER( nile_device::nile_sndctrl_w )
224165{
225   nile_state *info = get_safe_token(device);
166   UINT16 ctrl=m_ctrl;
226167
227   info->sound_ram = *device->region();
168   m_stream->update();
228169
229   info->stream = device->machine().sound().stream_alloc(*device, 0, 2, 44100, info, nile_update);
230}
170   COMBINE_DATA(&m_ctrl);
231171
232const device_type NILE = &device_creator<nile_device>;
172// printf("CTRL: %04x -> %04x (PC=%x)\n", ctrl, m_ctrl, space.device().safe_pc());
233173
234nile_device::nile_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
235   : device_t(mconfig, NILE, "NiLe", tag, owner, clock),
236     device_sound_interface(mconfig, *this)
237{
238   m_token = global_alloc_clear(nile_state);
174   ctrl^=m_ctrl;
239175}
240176
241//-------------------------------------------------
242//  device_config_complete - perform any
243//  operations now that the configuration is
244//  complete
245//-------------------------------------------------
246177
247void nile_device::device_config_complete()
178READ16_MEMBER( nile_device::nile_sndctrl_r )
248179{
180   m_stream->update();
181   return m_ctrl;
249182}
250183
251//-------------------------------------------------
252//  device_start - device-specific startup
253//-------------------------------------------------
254184
255void nile_device::device_start()
185READ16_MEMBER( nile_device::nile_snd_r )
256186{
257   DEVICE_START_NAME( nile )(this);
187   int reg=offset&0xf;
188
189   m_stream->update();
190
191   if(reg==2 || reg==3)
192   {
193      int slot=offset/16;
194      int sptr = ((m_sound_regs[slot*16+3]<<16)|m_sound_regs[slot*16+2])+m_vpos[slot];
195
196      if(reg==2)
197      {
198         return sptr&0xffff;
199      }
200      else
201      {
202         return sptr>>16;
203      }
204   }
205   return m_sound_regs[offset];
258206}
259207
260//-------------------------------------------------
261//  sound_stream_update - handle a stream update
262//-------------------------------------------------
263208
264void nile_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
209WRITE16_MEMBER( nile_device::nile_snd_w )
265210{
266   // should never get here
267   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
268}
211   int v, r;
269212
213   m_stream->update();
270214
215   COMBINE_DATA(&m_sound_regs[offset]);
216
217   v = offset / 16;
218   r = offset % 16;
219
220   if ((r == 2) || (r == 3))
221   {
222      m_vpos[v] = m_frac[v] = m_lponce[v] = 0;
223   }
224
225   //printf("v%02d: %04x to reg %02d (PC=%x)\n", v, m_sound_regs[offset], r, space.device().safe_pc());
226}
trunk/src/emu/sound/nile.h
r19924r19925
33#ifndef __NILE_H__
44#define __NILE_H__
55
6#include "devlegcy.h"
76
8DECLARE_WRITE16_DEVICE_HANDLER( nile_snd_w );
9DECLARE_READ16_DEVICE_HANDLER( nile_snd_r );
10DECLARE_WRITE16_DEVICE_HANDLER( nile_sndctrl_w );
11DECLARE_READ16_DEVICE_HANDLER( nile_sndctrl_r );
7//**************************************************************************
8//  INTERFACE CONFIGURATION MACROS
9//**************************************************************************
1210
11#define MCFG_NILE_ADD(_tag, _clock) \
12   MCFG_DEVICE_ADD(_tag, NILE, _clock) \
13
14#define MCFG_NILE_REPLACE(_tag, _clock) \
15   MCFG_DEVICE_REPLACE(_tag, NILE, _clock) \
16
17
18
19//**************************************************************************
20//  TYPE DEFINITIONS
21//**************************************************************************
22
23#define NILE_VOICES 8
24
25// ======================> nile_device
26
1327class nile_device : public device_t,
14                                  public device_sound_interface
28               public device_sound_interface
1529{
1630public:
1731   nile_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
18   ~nile_device() { global_free(m_token); }
32   ~nile_device() { }
1933
20   // access to legacy token
21   void *token() const { assert(m_token != NULL); return m_token; }
2234protected:
2335   // device-level overrides
24   virtual void device_config_complete();
2536   virtual void device_start();
2637
2738   // sound stream update overrides
2839   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
40
41public:
42   DECLARE_WRITE16_MEMBER( nile_snd_w );
43   DECLARE_READ16_MEMBER( nile_snd_r );
44   DECLARE_WRITE16_MEMBER( nile_sndctrl_w );
45   DECLARE_READ16_MEMBER( nile_sndctrl_r );
46
2947private:
30   // internal state
31   void *m_token;
48   sound_stream *m_stream;
49   UINT8 *m_sound_ram;
50   UINT16 m_sound_regs[0x80];
51   int m_vpos[NILE_VOICES];
52   int m_frac[NILE_VOICES];
53   int m_lponce[NILE_VOICES];
54   UINT16 m_ctrl;
3255};
3356
3457extern const device_type NILE;

Previous 199869 Revisions Next


© 1997-2024 The MAME Team