Previous 199869 Revisions Next

r22592 Sunday 28th April, 2013 at 15:17:52 UTC by R. Belmont
Free to good home if you can make it not sound like ass (nw)
[src/mess]mess.mak
[src/mess/audio]vrc6.c* vrc6.h*
[src/mess/machine]nes_konami.c nes_konami.h

trunk/src/mess/mess.mak
r22591r22592
14251425   $(MESS_MACHINE)/nes_jy.o  \
14261426   $(MESS_MACHINE)/nes_kaiser.o  \
14271427   $(MESS_MACHINE)/nes_konami.o  \
1428   $(MESS_AUDIO)/vrc6.o          \
14281429   $(MESS_MACHINE)/nes_legacy.o  \
14291430   $(MESS_MACHINE)/nes_multigame.o  \
14301431   $(MESS_MACHINE)/nes_namcot.o  \
trunk/src/mess/audio/vrc6.c
r0r22592
1/***************************************************************************
2
3    vrc6.c
4    Konami VRC6 additional sound channels
5
6    Emulation by R. Belmont
7 
8    References:
9    http://wiki.nesdev.com/w/index.php/VRC6_audio
10   http://nesdev.com/vrcvi.txt
11 
12***************************************************************************/
13
14#include "emu.h"
15#include "vrc6.h"
16
17#define DISABLE_VRC6_SOUND      // not ready yet
18
19// device type definition
20const device_type VRC6 = &device_creator<vrc6snd_device>;
21
22//**************************************************************************
23//  LIVE DEVICE
24//**************************************************************************
25
26//-------------------------------------------------
27//  vrc6snd_device - constructor
28//-------------------------------------------------
29
30vrc6snd_device::vrc6snd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
31   : device_t(mconfig, VRC6, "VRC6 sound", tag, owner, clock),
32     device_sound_interface(mconfig, *this)
33{
34}
35
36//-------------------------------------------------
37//  device_start - device-specific startup
38//-------------------------------------------------
39
40void vrc6snd_device::device_start()
41{
42   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock(), this);
43
44   m_freqctrl = m_pulsectrl[0] = m_pulsectrl[1] = 0;
45   m_pulsefrql[0] = m_pulsefrql[1] = m_pulsefrqh[0] = m_pulsefrqh[1] = 0;
46   m_sawaccum = m_sawfrql = m_sawfrqh = m_sawclock = m_sawrate = 0;
47   m_ticks[0] = m_ticks[1] = m_ticks[2] = 0;
48   m_output[0] = m_output[1] = m_output[2] = 0;
49   m_pulseduty[0] = m_pulseduty[1] = 15;
50
51   save_item(NAME(m_freqctrl));
52   save_item(NAME(m_pulsectrl));
53   save_item(NAME(m_sawrate));
54   save_item(NAME(m_sawaccum));
55   save_item(NAME(m_pulsefrql));
56   save_item(NAME(m_pulsefrqh));
57   save_item(NAME(m_sawfrql));
58   save_item(NAME(m_sawfrqh));
59   save_item(NAME(m_ticks));
60   save_item(NAME(m_output));
61   save_item(NAME(m_pulseduty));
62}
63
64
65//-------------------------------------------------
66//  device_reset - device-specific reset
67//-------------------------------------------------
68
69void vrc6snd_device::device_reset()
70{
71   m_stream->update();
72
73   m_freqctrl = m_pulsectrl[0] = m_pulsectrl[1] = 0;
74   m_pulsefrql[0] = m_pulsefrql[1] = 0;
75   m_sawaccum = m_sawfrql = m_sawclock = m_sawrate = 0;
76   m_ticks[0] = m_ticks[1] = m_ticks[2] = 0;
77   m_output[0] = m_output[1] = m_output[2] = 0;
78   m_pulseduty[0] = m_pulseduty[1] = 15;
79   m_pulsefrqh[0] = m_pulsefrqh[1] = m_sawfrqh = 0;
80}
81
82//-------------------------------------------------
83//  sound_stream_update - handle update requests for
84//  our sound stream
85//-------------------------------------------------
86
87void vrc6snd_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
88{
89   stream_sample_t *out = outputs[0];
90   INT16 tmp;
91   int i;
92
93   // check global halt bit
94   if (m_freqctrl & 1)
95   {
96      return;
97   }
98
99   for (i = 0; i < samples; i++)
100   {
101      // update pulse1
102      if (m_pulsefrqh[0] & 0x80)
103      {
104         m_ticks[0]--;
105         if (m_ticks[0] == 0)
106         {
107            m_ticks[0] = m_pulsefrql[0] | (m_pulsefrqh[0] & 0xf)<<4;
108
109            m_pulseduty[0]--;
110            if (m_pulsectrl[0] & 0x80)
111            {
112               m_output[0] = m_pulsectrl[0] & 0xf;
113            }
114            else
115            {
116               if (m_pulseduty[0] <= ((m_pulsectrl[0]>>4) & 0x7))
117               {
118                  m_output[0] = m_pulsectrl[0] & 0xf;
119               }
120               else
121               {
122                  m_output[0] = 0;
123               }
124            }
125
126            if (m_pulseduty[0] == 0)
127            {
128               m_pulseduty[0] = 15;
129            }
130         }
131      }
132      else
133      {
134         m_output[0] = 0;
135      }
136
137      // update pulse2
138      if (m_pulsefrqh[1] & 0x80)
139      {
140         m_ticks[1]--;
141         if (m_ticks[1] == 0)
142         {
143            m_ticks[1] = m_pulsefrql[1] | (m_pulsefrqh[1] & 0xf)<<4;
144
145            m_pulseduty[1]--;
146            if (m_pulsectrl[1] & 0x80)
147            {
148               m_output[1] = m_pulsectrl[1] & 0xf;
149            }
150            else
151            {
152               if (m_pulseduty[1] <= ((m_pulsectrl[1]>>4) & 0x7))
153               {
154                  m_output[1] = m_pulsectrl[1] & 0xf;
155               }
156               else
157               {
158                  m_output[1] = 0;
159               }
160            }
161
162            if (m_pulseduty[1] == 0)
163            {
164               m_pulseduty[1] = 15;
165            }
166         }
167      }
168      else
169      {
170         m_output[1] = 0;
171      }
172
173      // update saw
174      if (m_sawfrqh & 0x80)
175      {
176         m_ticks[2]--;
177         if (m_ticks[2] == 0)
178          {
179            m_ticks[2] = m_sawfrql | (m_sawfrqh & 0xf)<<4;
180
181            // only update on even steps
182            if ((m_sawclock > 0) && (!(m_sawclock & 1)))
183            {
184               m_sawaccum += (m_sawrate & 0x3f);
185               m_output[2] = (m_sawaccum>>3);
186            }
187            m_sawclock++;
188
189            if (m_sawclock >= 14)
190            {
191               m_sawclock = m_sawaccum = 0;
192               m_output[2] = 0;
193            }
194         }
195      }
196      else
197      {
198         m_output[2] = 0;
199      }
200
201      // sum 2 4-bit pulses, 1 5-bit saw = unsigned 6 bit output
202       tmp = (INT16)(UINT8)(m_output[0] + m_output[1] + m_output[2]);
203      tmp <<= 8;
204
205      out[i] = tmp;
206   }
207}
208
209//---------------------------------------
210//  write - write to the chip's registers
211//---------------------------------------
212
213WRITE8_MEMBER( vrc6snd_device::write )
214{
215   switch (offset >> 8)
216   {
217      case 0:
218         m_stream->update();
219         switch (offset & 3)
220         {
221            case 0:
222               m_pulsectrl[0] = data;
223               break;
224
225            case 1:
226               m_pulsefrql[0] = data;
227               if (!(m_pulsefrqh[1] & 0x80))
228               {
229                  m_ticks[0] &= ~0xff;
230                  m_ticks[0] |= m_pulsefrql[0];
231               }
232               break;
233
234            case 2:
235               #ifndef DISABLE_VRC6_SOUND
236               m_pulsefrqh[0] = data;
237               // if disabling channel, reset phase
238               if (!(data & 0x80))
239               {
240                  m_pulseduty[0] = 15;
241                  m_ticks[0] &= 0xff;
242                  m_ticks[0] |= (m_pulsefrqh[0] & 0xf)<<4;
243               }
244               #endif
245               break;
246
247            case 3:
248               m_freqctrl = data;
249               break;
250         }
251         break;
252
253      case 1:
254         m_stream->update();
255         switch (offset & 3)
256         {
257            case 0:
258               m_pulsectrl[1] = data;
259               break;
260
261            case 1:
262               m_pulsefrql[1] = data;
263               if (!(m_pulsefrqh[1] & 0x80))
264               {
265                  m_ticks[1] &= ~0xff;
266                  m_ticks[1] |= m_pulsefrql[1];
267               }
268               break;
269
270            case 2:
271               #ifndef DISABLE_VRC6_SOUND
272               m_pulsefrqh[1] = data;
273               // if disabling channel, reset phase
274               if (!(data & 0x80))
275               {
276                  m_pulseduty[1] = 15;
277                  m_ticks[1] &= 0xff;
278                  m_ticks[1] |= (m_pulsefrqh[1] & 0xf)<<4;
279               }
280               #endif
281               break;
282         }
283         break;
284
285      case 2:
286         m_stream->update();
287         switch (offset & 3)
288         {
289            case 0:
290               m_sawrate = data;
291               break;
292
293            case 1:
294               m_sawfrql = data;
295               if (!(m_sawfrqh & 0x80))
296               {
297                  m_ticks[2] &= ~0xff;
298                  m_ticks[2] |= m_sawfrql;
299               }
300               break;
301
302            case 2:
303               #ifndef DISABLE_VRC6_SOUND
304               m_sawfrqh = data;
305               // if disabling channel, reset phase
306               if (!(data & 0x80))
307               {
308                  m_sawaccum = 0;
309                  m_ticks[2] &= 0xff;
310                  m_ticks[2] |= (m_sawfrqh & 0xf)<<4;
311               }
312               #endif
313               break;
314         }
315         break;
316   }
317
318}
319
320
Property changes on: trunk/src/mess/audio/vrc6.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/audio/vrc6.h
r0r22592
1/***************************************************************************
2
3    vrc6.h
4    Konami VRC6 add-on sound
5
6***************************************************************************/
7
8#pragma once
9
10#ifndef __VRC6_H__
11#define __VRC6_H__
12
13//**************************************************************************
14//  INTERFACE CONFIGURATION MACROS
15//**************************************************************************
16
17#define MCFG_VRC6_ADD(_tag, _clock) \
18   MCFG_DEVICE_ADD(_tag, VRC6, _clock)
19
20#define MCFG_VRC6_REPLACE(_tag, _clock) \
21   MCFG_DEVICE_REPLACE(_tag, VRC6, _clock)
22
23//**************************************************************************
24//  TYPE DEFINITIONS
25//**************************************************************************
26
27// ======================> vrc6snd_device
28
29class vrc6snd_device : public device_t, public device_sound_interface
30{
31public:
32   // construction/destruction
33   vrc6snd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
34
35   DECLARE_WRITE8_MEMBER(write);
36
37protected:
38   // device-level overrides
39   virtual void device_start();
40   virtual void device_reset();
41
42   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
43
44private:
45   UINT8 m_freqctrl, m_pulsectrl[2], m_sawrate;
46   UINT8 m_pulsefrql[2], m_pulsefrqh[2], m_pulseduty[2];
47   UINT8 m_sawfrql, m_sawfrqh, m_sawclock, m_sawaccum;
48   UINT16 m_ticks[3];
49   UINT8 m_output[3];
50
51   sound_stream *m_stream;
52};
53
54
55// device type definition
56extern const device_type VRC6;
57
58
59#endif /* __VRC6_H__ */
60
61
Property changes on: trunk/src/mess/audio/vrc6.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/nes_konami.c
r22591r22592
3939
4040#define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0)
4141
42#define N2A03_DEFAULTCLOCK (21477272.724 / 12)
4243
4344//-------------------------------------------------
4445//  constructor
r22591r22592
7879}
7980
8081nes_konami_vrc6_device::nes_konami_vrc6_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
81               : nes_konami_vrc4_device(mconfig, NES_VRC6, "NES Cart Konami VRC-6 PCB", tag, owner, clock, "nes_vrc6", __FILE__)
82               : nes_konami_vrc4_device(mconfig, NES_VRC6, "NES Cart Konami VRC-6 PCB", tag, owner, clock, "nes_vrc6", __FILE__),
83               m_vrc6snd(*this, "vrc6snd")
8284{
8385}
8486
r22591r22592
187189   memset(m_mmc_vrom_bank, 0, sizeof(m_mmc_vrom_bank));
188190}
189191
192void nes_konami_vrc6_device::device_start()
193{
194   nes_konami_vrc4_device::device_start();
195}
196
190197void nes_konami_vrc7_device::device_start()
191198{
192199   m_ym2413 = device().subdevice("ym");
r22591r22592
573580      case 0x4000:
574581         prg8_cd(data);
575582         break;
576      case 0x1000:
577      case 0x2000:
578         LOG_MMC(("Konami VRC-6 Sound write, offset: %04x, data: %02x\n", (offset & 0x7000) | add_lines, data));
583      case 0x1000:   // pulse 1 & global control
584         m_vrc6snd->write(space, add_lines>>8, data);
579585         break;
586      case 0x2000:   // pulse 2
587         m_vrc6snd->write(space, (add_lines>>8) | 0x100, data);
588         break;
580589      case 0x3000:
581590         if (add_lines == 0x300)
582591         {
r22591r22592
588597               case 0x0c: set_nt_mirroring(PPU_MIRROR_HIGH); break;
589598            }
590599         }
591         else
592            LOG_MMC(("Konami VRC-6 Sound write, offset: %04x, data: %02x\n", (offset & 0x7000) | add_lines, data));
600         else   // saw
601         {
602            m_vrc6snd->write(space, (add_lines>>8) | 0x200, data);
603         }
593604         break;
594605      case 0x5000:
595606      case 0x6000:
r22591r22592
623634   }
624635}
625636
637static MACHINE_CONFIG_FRAGMENT( vrc6 )
638
639   // additional sound hardware
640   MCFG_SPEAKER_STANDARD_MONO("addon")
641
642   MCFG_SOUND_ADD("vrc6snd", VRC6, N2A03_DEFAULTCLOCK)
643   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "addon", 0.5)
644MACHINE_CONFIG_END
645
646//-------------------------------------------------
647//  machine_config_additions - device-specific
648//  machine configurations
649//-------------------------------------------------
650
651machine_config_constructor nes_konami_vrc6_device::device_mconfig_additions() const
652{
653   return MACHINE_CONFIG_NAME( vrc6 );
654}
655
626656/*-------------------------------------------------
627657
628658 Konami VRC7
trunk/src/mess/machine/nes_konami.h
r22591r22592
22#define __NES_KONAMI_H
33
44#include "machine/nes_nxrom.h"
5#include "audio/vrc6.h"
56
67
78// ======================> nes_konami_vrc1_device
r22591r22592
111112   nes_konami_vrc6_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
112113
113114   // device-level overrides
115   virtual void device_start();
116   virtual machine_config_constructor device_mconfig_additions() const;
114117   virtual DECLARE_WRITE8_MEMBER(write_h);
115118
116   // TODO: emulate sound capabilities!
119   required_device<vrc6snd_device> m_vrc6snd;
117120};
118121
119122

Previous 199869 Revisions Next


© 1997-2024 The MAME Team