Previous 199869 Revisions Next

r24636 Thursday 1st August, 2013 at 23:34:10 UTC by Tafoid
Modernized the s14001a and exidy sound devices.  [Osso]
[src/emu/sound]s14001a.c s14001a.h
[src/mame/audio]exidy.c exidy.h
[src/mame/drivers]berzerk.c victory.c wolfpack.c
[src/mame/includes]wolfpack.h
[src/mess/drivers]csc.c fidelz80.c

trunk/src/mame/includes/wolfpack.h
r24635r24636
1#include "sound/s14001a.h"
2
13class wolfpack_state : public driver_device
24{
35public:
r24635r24636
911   wolfpack_state(const machine_config &mconfig, device_type type, const char *tag)
1012      : driver_device(mconfig, type, tag),
1113      m_alpha_num_ram(*this, "alpha_num_ram"),
12      m_maincpu(*this, "maincpu") { }
14      m_maincpu(*this, "maincpu"),
15      m_s14001a(*this, "speech") { }
1316
17   required_shared_ptr<UINT8> m_alpha_num_ram;
18   
19   required_device<cpu_device> m_maincpu;
20   required_device<s14001a_device> m_s14001a;
21   
1422   int m_collision;
15   required_shared_ptr<UINT8> m_alpha_num_ram;
1623   unsigned m_current_index;
1724   UINT8 m_video_invert;
1825   UINT8 m_ship_reflect;
r24635r24636
6774   void draw_torpedo(bitmap_ind16 &bitmap, const rectangle &cliprect);
6875   void draw_pt(bitmap_ind16 &bitmap, const rectangle &cliprect);
6976   void draw_water(colortable_t *colortable, bitmap_ind16 &bitmap, const rectangle &cliprect);
70   required_device<cpu_device> m_maincpu;
7177
7278protected:
7379   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
trunk/src/mame/drivers/victory.c
r24635r24636
133133   AM_RANGE(0xc800, 0xdfff) AM_RAM AM_SHARE("charram")
134134   AM_RANGE(0xe000, 0xefff) AM_RAM
135135   AM_RANGE(0xf000, 0xf7ff) AM_RAM AM_SHARE("nvram")
136   AM_RANGE(0xf800, 0xf800) AM_MIRROR(0x07fc) AM_DEVREADWRITE_LEGACY("custom", victory_sound_response_r, victory_sound_command_w)
137   AM_RANGE(0xf801, 0xf801) AM_MIRROR(0x07fc) AM_DEVREAD_LEGACY("custom", victory_sound_status_r)
136   AM_RANGE(0xf800, 0xf800) AM_MIRROR(0x07fc) AM_DEVREADWRITE("custom", victory_sound_device, response_r, command_w)
137   AM_RANGE(0xf801, 0xf801) AM_MIRROR(0x07fc) AM_DEVREAD("custom", victory_sound_device, status_r)
138138ADDRESS_MAP_END
139139
140140
trunk/src/mame/drivers/berzerk.c
r24635r24636
2525      : driver_device(mconfig, type, tag),
2626      m_videoram(*this, "videoram"),
2727      m_colorram(*this, "colorram"),
28      m_maincpu(*this, "maincpu") { }
28      m_maincpu(*this, "maincpu"),
29      m_s14001a(*this, "speech"),
30      m_custom(*this, "exidy") { }
2931
3032   required_shared_ptr<UINT8> m_videoram;
3133   required_shared_ptr<UINT8> m_colorram;
34   
35   required_device<cpu_device> m_maincpu;
36   required_device<s14001a_device> m_s14001a;
37   required_device<exidy_sound_device> m_custom;
38     
3239   UINT8 m_magicram_control;
3340   UINT8 m_last_shift_data;
3441   UINT8 m_intercept;
r24635r24636
7077   void create_nmi_timer();
7178   void start_nmi_timer();
7279   void get_pens(pen_t *pens);
73   required_device<cpu_device> m_maincpu;
7480};
7581
7682
r24635r24636
511517
512518WRITE8_MEMBER(berzerk_state::berzerk_audio_w)
513519{
514   device_t *device;
515520   int clock_divisor;
516521
517522   switch (offset)
518523   {
519524   /* offset 4 writes to the S14001A */
520525   case 4:
521      device = machine().device("speech");
522526      switch (data >> 6)
523527      {
524528      /* write data to the S14001 */
525529      case 0:
526530         /* only if not busy */
527         if (!s14001a_bsy_r(device))
531         if (!m_s14001a->bsy_r())
528532         {
529            s14001a_reg_w(device, data & 0x3f);
533            m_s14001a->reg_w(data & 0x3f);
530534
531535            /* clock the chip -- via a 555 timer */
532            s14001a_rst_w(device, 1);
533            s14001a_rst_w(device, 0);
536            m_s14001a->rst_w(1);
537            m_s14001a->rst_w(0);
534538         }
535539
536540         break;
537541
538542      case 1:
539         device = machine().device("speech");
540543         /* volume */
541         s14001a_set_volume(device, ((data & 0x38) >> 3) + 1);
544         m_s14001a->set_volume(((data & 0x38) >> 3) + 1);
542545
543546         /* clock control - the first LS161 divides the clock by 9 to 16, the 2nd by 8,
544547            giving a final clock from 19.5kHz to 34.7kHz */
545548         clock_divisor = 16 - (data & 0x07);
546549
547         s14001a_set_clock(device, S14001_CLOCK / clock_divisor / 8);
550         m_s14001a->set_clock(S14001_CLOCK / clock_divisor / 8);
548551         break;
549552
550553      default: break; /* 2 and 3 are not connected */
r24635r24636
554557
555558   /* offset 6 writes to the sfxcontrol latch */
556559   case 6:
557      exidy_sfxctrl_w(machine().device("exidy"), space, data >> 6, data);
560      m_custom->sfxctrl_w(space, data >> 6, data);
558561      break;
559562
560563   /* everything else writes to the 6840 */
561564   default:
562      exidy_sh6840_w(machine().device("exidy"), space, offset, data);
565      m_custom->sh6840_w(space, offset, data);
563566      break;
564567
565568   }
r24635r24636
568571
569572READ8_MEMBER(berzerk_state::berzerk_audio_r)
570573{
571   device_t *device = machine().device("speech");
572574   switch (offset)
573575   {
574576   /* offset 4 reads from the S14001A */
575577   case 4:
576      return (!s14001a_bsy_r(device)) ? 0x40 : 0x00;
578      return (!m_s14001a->bsy_r()) ? 0x40 : 0x00;
577579   /* offset 6 is open bus */
578580   case 6:
579581      logerror("attempted read from berzerk audio reg 6 (sfxctrl)!\n");
580582      return 0;
581583   /* everything else reads from the 6840 */
582584   default:
583      return exidy_sh6840_r(machine().device("exidy"), space, offset);
585      return m_custom->sh6840_r(space, offset);
584586   }
585587}
586588
trunk/src/mame/drivers/wolfpack.c
r24635r24636
66
77#include "emu.h"
88#include "cpu/m6502/m6502.h"
9#include "sound/s14001a.h"
109#include "includes/wolfpack.h"
1110
1211
r24635r24636
5352
5453READ8_MEMBER(wolfpack_state::wolfpack_misc_r)
5554{
56   device_t *device = machine().device("speech");
5755   UINT8 val = 0;
5856
5957   /* BIT0 => SPEECH BUSY */
r24635r24636
6563   /* BIT6 => UNUSED      */
6664   /* BIT7 => VBLANK      */
6765
68   if (!s14001a_bsy_r(device))
66   if (!m_s14001a->bsy_r())
6967      val |= 0x01;
7068
7169   if (!m_collision)
r24635r24636
9189
9290WRITE8_MEMBER(wolfpack_state::wolfpack_word_w)
9391{
94   device_t *device = machine().device("speech");
95      /* latch word from bus into temp register, and place on s14001a input bus */
96      /* there is no real need for a temp register at all, since the bus 'register' acts as one */
97      s14001a_reg_w(device, data & 0x1f); /* SA0 (IN5) is pulled low according to the schematic, so its 0x1f and not 0x3f as one would expect */
92   /* latch word from bus into temp register, and place on s14001a input bus */
93   /* there is no real need for a temp register at all, since the bus 'register' acts as one */
94   m_s14001a->reg_w(data & 0x1f); /* SA0 (IN5) is pulled low according to the schematic, so its 0x1f and not 0x3f as one would expect */
9895}
9996
10097WRITE8_MEMBER(wolfpack_state::wolfpack_start_speech_w)
10198{
102   device_t *device = machine().device("speech");
103      s14001a_set_volume(device, 15); /* hack, should be executed just once during game init, or defaulted to this in the s14001a core */
104      s14001a_rst_w(device, data&1);
99   m_s14001a->set_volume(15); /* hack, should be executed just once during game init, or defaulted to this in the s14001a core */
100   m_s14001a->rst_w(data&1);
105101}
106102
107103
trunk/src/mame/audio/exidy.c
r24635r24636
88#include "cpu/z80/z80.h"
99#include "machine/rescap.h"
1010#include "cpu/m6502/m6502.h"
11#include "machine/6821pia.h"
12#include "machine/6532riot.h"
13#include "sound/hc55516.h"
14#include "sound/tms5220.h"
1511#include "audio/exidy.h"
16#include "devlegcy.h"
1712
1813
1914
r24635r24636
3934};
4035
4136
42
4337/*************************************
4438 *
45 *  Local variables
46 *
47 *************************************/
48
49/* 6840 variables */
50struct sh6840_timer_channel
51{
52   UINT8   cr;
53   UINT8   state;
54   UINT8   leftovers;
55   UINT16  timer;
56   UINT32  clocks;
57   union
58   {
59#ifdef LSB_FIRST
60      struct { UINT8 l, h; } b;
61#else
62      struct { UINT8 h, l; } b;
63#endif
64      UINT16 w;
65   } counter;
66};
67
68struct sh8253_timer_channel
69{
70   UINT8   clstate;
71   UINT8   enable;
72   UINT16  count;
73   UINT32  step;
74   UINT32  fraction;
75};
76
77struct exidy_sound_state
78{
79   cpu_device *m_maincpu;
80
81   /* IRQ variable */
82   UINT8 m_riot_irq_state;
83
84   /* 6532 variables */
85   riot6532_device *m_riot;
86
87   struct sh6840_timer_channel m_sh6840_timer[3];
88   INT16 m_sh6840_volume[3];
89   UINT8 m_sh6840_MSB_latch;
90   UINT8 m_sh6840_LSB_latch;
91   UINT8 m_sh6840_LFSR_oldxor;
92   UINT32 m_sh6840_LFSR_0;
93   UINT32 m_sh6840_LFSR_1;
94   UINT32 m_sh6840_LFSR_2;
95   UINT32 m_sh6840_LFSR_3;
96   UINT32 m_sh6840_clocks_per_sample;
97   UINT32 m_sh6840_clock_count;
98
99   UINT8 m_sfxctrl;
100
101   /* 8253 variables */
102   struct sh8253_timer_channel m_sh8253_timer[3];
103   int m_has_sh8253;
104
105   /* 5220/CVSD variables */
106   hc55516_device *m_cvsd;
107   tms5220_device *m_tms;
108   pia6821_device *m_pia1;
109
110   /* sound streaming variables */
111   sound_stream *m_stream;
112   double m_freq_to_step;
113
114   UINT8 m_victory_sound_response_ack_clk; /* 7474 @ F4 */
115};
116
117
118INLINE exidy_sound_state *get_safe_token(device_t *device)
119{
120   assert(device != NULL);
121   assert(device->type() == EXIDY || device->type() == EXIDY_VENTURE || device->type() == EXIDY_VICTORY);
122
123   return (exidy_sound_state *)downcast<exidy_sound_device *>(device)->token();
124}
125
126/*************************************
127 *
12839 *  Interrupt generation helper
12940 *
13041 *************************************/
13142
132static WRITE_LINE_DEVICE_HANDLER( update_irq_state )
43WRITE_LINE_MEMBER( exidy_sound_device::update_irq_state )
13344{
134   exidy_sound_state *sndstate = get_safe_token(device);
135   device->machine().device("audiocpu")->execute().set_input_line(M6502_IRQ_LINE, (sndstate->m_pia1->irq_b_state() | sndstate->m_riot_irq_state) ? ASSERT_LINE : CLEAR_LINE);
45   machine().device("audiocpu")->execute().set_input_line(M6502_IRQ_LINE, (m_pia1->irq_b_state() | m_riot_irq_state) ? ASSERT_LINE : CLEAR_LINE);
13646}
13747
13848
r24635r24636
198108 *
199109 *************************************/
200110
201INLINE int sh6840_update_noise(exidy_sound_state *state, int clocks)
111inline int exidy_sound_device::sh6840_update_noise(int clocks)
202112{
203113   UINT32 newxor;
204114   int noise_clocks = 0;
r24635r24636
212122      * first we grab new sample, then shift the high bits,
213123      * then the low ones; finally or in the result and see if we've
214124      * had a 0->1 transition */
215      newxor = (state->m_sh6840_LFSR_3 ^ state->m_sh6840_LFSR_2) >> 31; /* high bits of 3 and 2 xored is new xor */
216      state->m_sh6840_LFSR_3 <<= 1;
217      state->m_sh6840_LFSR_3 |= state->m_sh6840_LFSR_2 >> 31;
218      state->m_sh6840_LFSR_2 <<= 1;
219      state->m_sh6840_LFSR_2 |= state->m_sh6840_LFSR_1 >> 31;
220      state->m_sh6840_LFSR_1 <<= 1;
221      state->m_sh6840_LFSR_1 |= state->m_sh6840_LFSR_0 >> 31;
222      state->m_sh6840_LFSR_0 <<= 1;
223      state->m_sh6840_LFSR_0 |= newxor ^ state->m_sh6840_LFSR_oldxor;
224      state->m_sh6840_LFSR_oldxor = newxor;
125      newxor = (m_sh6840_LFSR_3 ^ m_sh6840_LFSR_2) >> 31; /* high bits of 3 and 2 xored is new xor */
126      m_sh6840_LFSR_3 <<= 1;
127      m_sh6840_LFSR_3 |= m_sh6840_LFSR_2 >> 31;
128      m_sh6840_LFSR_2 <<= 1;
129      m_sh6840_LFSR_2 |= m_sh6840_LFSR_1 >> 31;
130      m_sh6840_LFSR_1 <<= 1;
131      m_sh6840_LFSR_1 |= m_sh6840_LFSR_0 >> 31;
132      m_sh6840_LFSR_0 <<= 1;
133      m_sh6840_LFSR_0 |= newxor ^ m_sh6840_LFSR_oldxor;
134      m_sh6840_LFSR_oldxor = newxor;
225135      /*printf("LFSR: %4x, %4x, %4x, %4x\n", sh6840_LFSR_3, sh6840_LFSR_2, sh6840_LFSR_1, sh6840_LFSR_0);*/
226136      /* if we clocked 0->1, that will serve as an external clock */
227      if ((state->m_sh6840_LFSR_2 & 0x03) == 0x01) /* tap is at 96th bit */
137      if ((m_sh6840_LFSR_2 & 0x03) == 0x01) /* tap is at 96th bit */
228138      {
229139         noise_clocks++;
230140      }
r24635r24636
240150 *
241151 *************************************/
242152
243static void sh6840_register_state_globals(device_t *device)
153void exidy_sound_device::sh6840_register_state_globals()
244154{
245   exidy_sound_state *state = get_safe_token(device);
246
247   device->save_item(NAME(state->m_sh6840_volume));
248   device->save_item(NAME(state->m_sh6840_MSB_latch));
249   device->save_item(NAME(state->m_sh6840_LSB_latch));
250   device->save_item(NAME(state->m_sh6840_LFSR_oldxor));
251   device->save_item(NAME(state->m_sh6840_LFSR_0));
252   device->save_item(NAME(state->m_sh6840_LFSR_1));
253   device->save_item(NAME(state->m_sh6840_LFSR_2));
254   device->save_item(NAME(state->m_sh6840_LFSR_3));
255   device->save_item(NAME(state->m_sh6840_clock_count));
256   device->save_item(NAME(state->m_sfxctrl));
257   device->save_item(NAME(state->m_sh6840_timer[0].cr));
258   device->save_item(NAME(state->m_sh6840_timer[0].state));
259   device->save_item(NAME(state->m_sh6840_timer[0].leftovers));
260   device->save_item(NAME(state->m_sh6840_timer[0].timer));
261   device->save_item(NAME(state->m_sh6840_timer[0].clocks));
262   device->save_item(NAME(state->m_sh6840_timer[0].counter.w));
263   device->save_item(NAME(state->m_sh6840_timer[1].cr));
264   device->save_item(NAME(state->m_sh6840_timer[1].state));
265   device->save_item(NAME(state->m_sh6840_timer[1].leftovers));
266   device->save_item(NAME(state->m_sh6840_timer[1].timer));
267   device->save_item(NAME(state->m_sh6840_timer[1].clocks));
268   device->save_item(NAME(state->m_sh6840_timer[1].counter.w));
269   device->save_item(NAME(state->m_sh6840_timer[2].cr));
270   device->save_item(NAME(state->m_sh6840_timer[2].state));
271   device->save_item(NAME(state->m_sh6840_timer[2].leftovers));
272   device->save_item(NAME(state->m_sh6840_timer[2].timer));
273   device->save_item(NAME(state->m_sh6840_timer[2].clocks));
274   device->save_item(NAME(state->m_sh6840_timer[2].counter.w));
155   save_item(NAME(m_sh6840_volume));
156   save_item(NAME(m_sh6840_MSB_latch));
157   save_item(NAME(m_sh6840_LSB_latch));
158   save_item(NAME(m_sh6840_LFSR_oldxor));
159   save_item(NAME(m_sh6840_LFSR_0));
160   save_item(NAME(m_sh6840_LFSR_1));
161   save_item(NAME(m_sh6840_LFSR_2));
162   save_item(NAME(m_sh6840_LFSR_3));
163   save_item(NAME(m_sh6840_clock_count));
164   save_item(NAME(m_sfxctrl));
165   save_item(NAME(m_sh6840_timer[0].cr));
166   save_item(NAME(m_sh6840_timer[0].state));
167   save_item(NAME(m_sh6840_timer[0].leftovers));
168   save_item(NAME(m_sh6840_timer[0].timer));
169   save_item(NAME(m_sh6840_timer[0].clocks));
170   save_item(NAME(m_sh6840_timer[0].counter.w));
171   save_item(NAME(m_sh6840_timer[1].cr));
172   save_item(NAME(m_sh6840_timer[1].state));
173   save_item(NAME(m_sh6840_timer[1].leftovers));
174   save_item(NAME(m_sh6840_timer[1].timer));
175   save_item(NAME(m_sh6840_timer[1].clocks));
176   save_item(NAME(m_sh6840_timer[1].counter.w));
177   save_item(NAME(m_sh6840_timer[2].cr));
178   save_item(NAME(m_sh6840_timer[2].state));
179   save_item(NAME(m_sh6840_timer[2].leftovers));
180   save_item(NAME(m_sh6840_timer[2].timer));
181   save_item(NAME(m_sh6840_timer[2].clocks));
182   save_item(NAME(m_sh6840_timer[2].counter.w));
275183}
276184
277
278
279185/*************************************
280186 *
281 *  Core sound generation
187 *  Audio startup routines
282188 *
283189 *************************************/
284190
285static STREAM_UPDATE( exidy_stream_update )
191void exidy_sound_device::common_sh_start()
286192{
287   exidy_sound_state *state = get_safe_token(device);
288   struct sh6840_timer_channel *sh6840_timer = state->m_sh6840_timer;
193   int sample_rate = SH8253_CLOCK;
289194
195   m_sh6840_clocks_per_sample = (int)((double)SH6840_CLOCK / (double)sample_rate * (double)(1 << 24));
196
197   /* allocate the stream */
198   m_stream = machine().sound().stream_alloc(*this, 0, 1, sample_rate, this);
199   m_maincpu = machine().device<cpu_device>("maincpu");
200
201   sh6840_register_state_globals();
202}
203
204const device_type EXIDY = &device_creator<exidy_sound_device>;
205
206exidy_sound_device::exidy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
207   : device_t(mconfig, EXIDY, "Exidy SFX", tag, owner, clock, "exidy_sfx", __FILE__),
208      device_sound_interface(mconfig, *this)
209{
210}
211
212exidy_sound_device::exidy_sound_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)
213   : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
214      device_sound_interface(mconfig, *this),
215      m_riot_irq_state(0),
216      m_stream(NULL),
217      m_freq_to_step(0),
218      m_sh6840_MSB_latch(0),
219      m_sh6840_LSB_latch(0),
220      m_sh6840_LFSR_oldxor(0),
221      m_sh6840_LFSR_0(0xffffffff),
222      m_sh6840_LFSR_1(0xffffffff),
223      m_sh6840_LFSR_2(0xffffffff),
224      m_sh6840_LFSR_3(0xffffffff),
225      m_sh6840_clocks_per_sample(0),
226      m_sh6840_clock_count(0),
227      m_sfxctrl(0)
228{
229}
230
231//-------------------------------------------------
232//  device_config_complete - perform any
233//  operations now that the configuration is
234//  complete
235//-------------------------------------------------
236
237void exidy_sound_device::device_config_complete()
238{
239}
240
241//-------------------------------------------------
242//  device_start - device-specific startup
243//-------------------------------------------------
244
245void exidy_sound_device::device_start()
246{
247   /* indicate no additional hardware */
248   m_has_sh8253  = FALSE;
249   m_tms = NULL;
250   m_cvsd = NULL;
251
252   common_sh_start();
253}
254
255//-------------------------------------------------
256//  device_reset - device-specific reset
257//-------------------------------------------------
258
259void exidy_sound_device::device_reset()
260{
261   common_sh_reset();
262}
263
264//-------------------------------------------------
265//  sound_stream_update - handle a stream update
266//-------------------------------------------------
267
268void exidy_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
269{
270   struct sh6840_timer_channel *sh6840_timer = m_sh6840_timer;
271
290272   /* hack to skip the expensive lfsr noise generation unless at least one of the 3 channels actually depends on it being generated */
291273   int noisy = ((sh6840_timer[0].cr & sh6840_timer[1].cr & sh6840_timer[2].cr & 0x02) == 0);
292274   stream_sample_t *buffer = outputs[0];
r24635r24636
301283      INT16 sample = 0;
302284
303285      /* determine how many 6840 clocks this sample */
304      state->m_sh6840_clock_count += state->m_sh6840_clocks_per_sample;
305      clocks_this_sample = state->m_sh6840_clock_count >> 24;
306      state->m_sh6840_clock_count &= (1 << 24) - 1;
286      m_sh6840_clock_count += m_sh6840_clocks_per_sample;
287      clocks_this_sample = m_sh6840_clock_count >> 24;
288      m_sh6840_clock_count &= (1 << 24) - 1;
307289
308290      /* skip if nothing enabled */
309291      if ((sh6840_timer[0].cr & 0x01) == 0)
r24635r24636
312294         UINT32 chan0_clocks;
313295
314296         /* generate E-clocked noise if configured to do so */
315         if (noisy && !(state->m_sfxctrl & 0x01))
316            noise_clocks_this_sample = sh6840_update_noise(state, clocks_this_sample);
297         if (noisy && !(m_sfxctrl & 0x01))
298            noise_clocks_this_sample = sh6840_update_noise(clocks_this_sample);
317299
318300         /* handle timer 0 if enabled */
319301         t = &sh6840_timer[0];
320302         chan0_clocks = t->clocks;
321303         clocks = (t->cr & 0x02) ? clocks_this_sample : noise_clocks_this_sample;
322304         sh6840_apply_clock(t, clocks);
323         if (t->state && !(state->m_sfxctrl & 0x02) && (t->cr & 0x80))
324            sample += state->m_sh6840_volume[0];
305         if (t->state && !(m_sfxctrl & 0x02) && (t->cr & 0x80))
306            sample += m_sh6840_volume[0];
325307
326308         /* generate channel 0-clocked noise if configured to do so */
327         if (noisy && (state->m_sfxctrl & 0x01))
328            noise_clocks_this_sample = sh6840_update_noise(state, t->clocks - chan0_clocks);
309         if (noisy && (m_sfxctrl & 0x01))
310            noise_clocks_this_sample = sh6840_update_noise(t->clocks - chan0_clocks);
329311
330312         /* handle timer 1 if enabled */
331313         t = &sh6840_timer[1];
332314         clocks = (t->cr & 0x02) ? clocks_this_sample : noise_clocks_this_sample;
333315         sh6840_apply_clock(t, clocks);
334316         if (t->state && (t->cr & 0x80))
335            sample += state->m_sh6840_volume[1];
317            sample += m_sh6840_volume[1];
336318
337319         /* handle timer 2 if enabled */
338320         t = &sh6840_timer[2];
r24635r24636
346328         }
347329         sh6840_apply_clock(t, clocks);
348330         if (t->state && (t->cr & 0x80))
349            sample += state->m_sh6840_volume[2];
331            sample += m_sh6840_volume[2];
350332      }
351333
352334      /* music (if present) */
353      if (state->m_has_sh8253)
335      if (m_has_sh8253)
354336      {
355337         /* music channel 0 */
356         c = &state->m_sh8253_timer[0];
338         c = &m_sh8253_timer[0];
357339         if (c->enable)
358340         {
359341            c->fraction += c->step;
r24635r24636
362344         }
363345
364346         /* music channel 1 */
365         c = &state->m_sh8253_timer[1];
347         c = &m_sh8253_timer[1];
366348         if (c->enable)
367349         {
368350            c->fraction += c->step;
r24635r24636
371353         }
372354
373355         /* music channel 2 */
374         c = &state->m_sh8253_timer[2];
356         c = &m_sh8253_timer[2];
375357         if (c->enable)
376358         {
377359            c->fraction += c->step;
r24635r24636
389371
390372/*************************************
391373 *
392 *  Audio startup routines
393 *
394 *************************************/
395
396static DEVICE_START( common_sh_start )
397{
398   exidy_sound_state *state = get_safe_token(device);
399   int sample_rate = SH8253_CLOCK;
400
401   state->m_sh6840_clocks_per_sample = (int)((double)SH6840_CLOCK / (double)sample_rate * (double)(1 << 24));
402
403   /* allocate the stream */
404   state->m_stream = device->machine().sound().stream_alloc(*device, 0, 1, sample_rate, NULL, exidy_stream_update);
405   state->m_maincpu = device->machine().device<cpu_device>("maincpu");
406
407   sh6840_register_state_globals(device);
408}
409
410static DEVICE_START( exidy_sound )
411{
412   exidy_sound_state *state = get_safe_token(device);
413
414   /* indicate no additional hardware */
415   state->m_has_sh8253  = FALSE;
416   state->m_tms = NULL;
417   state->m_cvsd = NULL;
418
419   DEVICE_START_CALL(common_sh_start);
420}
421
422const device_type EXIDY = &device_creator<exidy_sound_device>;
423
424exidy_sound_device::exidy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
425   : device_t(mconfig, EXIDY, "Exidy SFX", tag, owner, clock, "exidy_sfx", __FILE__),
426      device_sound_interface(mconfig, *this)
427{
428   m_token = global_alloc_clear(exidy_sound_state);
429}
430
431exidy_sound_device::exidy_sound_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)
432   : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
433      device_sound_interface(mconfig, *this)
434{
435   m_token = global_alloc_clear(exidy_sound_state);
436}
437
438//-------------------------------------------------
439//  device_config_complete - perform any
440//  operations now that the configuration is
441//  complete
442//-------------------------------------------------
443
444void exidy_sound_device::device_config_complete()
445{
446}
447
448//-------------------------------------------------
449//  device_start - device-specific startup
450//-------------------------------------------------
451
452void exidy_sound_device::device_start()
453{
454   DEVICE_START_NAME( exidy_sound )(this);
455}
456
457//-------------------------------------------------
458//  device_reset - device-specific reset
459//-------------------------------------------------
460
461static DEVICE_RESET( exidy_sound );
462
463void exidy_sound_device::device_reset()
464{
465   DEVICE_RESET_NAME( exidy_sound )(this);
466}
467
468//-------------------------------------------------
469//  sound_stream_update - handle a stream update
470//-------------------------------------------------
471
472void exidy_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
473{
474   // should never get here
475   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
476}
477
478
479
480/*************************************
481 *
482374 *  Audio reset routines
483375 *
484376 *************************************/
485377
486static DEVICE_RESET( common_sh_reset )
378void exidy_sound_device::common_sh_reset()
487379{
488   exidy_sound_state *state = get_safe_token(device);
489
490380   /* 6840 */
491   memset(state->m_sh6840_timer, 0, sizeof(state->m_sh6840_timer));
492   state->m_sh6840_MSB_latch = 0;
493   state->m_sh6840_LSB_latch = 0;
494   state->m_sh6840_volume[0] = 0;
495   state->m_sh6840_volume[1] = 0;
496   state->m_sh6840_volume[2] = 0;
497   state->m_sh6840_clock_count = 0;
498   state->m_sfxctrl = 0;
381   memset(m_sh6840_timer, 0, sizeof(m_sh6840_timer));
382   m_sh6840_MSB_latch = 0;
383   m_sh6840_LSB_latch = 0;
384   m_sh6840_volume[0] = 0;
385   m_sh6840_volume[1] = 0;
386   m_sh6840_volume[2] = 0;
387   m_sh6840_clock_count = 0;
388   m_sfxctrl = 0;
499389
500390   /* LFSR */
501   state->m_sh6840_LFSR_oldxor = 0;
502   state->m_sh6840_LFSR_0 = 0xffffffff;
503   state->m_sh6840_LFSR_1 = 0xffffffff;
504   state->m_sh6840_LFSR_2 = 0xffffffff;
505   state->m_sh6840_LFSR_3 = 0xffffffff;
391   m_sh6840_LFSR_oldxor = 0;
392   m_sh6840_LFSR_0 = 0xffffffff;
393   m_sh6840_LFSR_1 = 0xffffffff;
394   m_sh6840_LFSR_2 = 0xffffffff;
395   m_sh6840_LFSR_3 = 0xffffffff;
506396}
507397
508static DEVICE_RESET( exidy_sound )
509{
510   DEVICE_RESET_CALL(common_sh_reset);
511}
512398
513
514399/*************************************
515400 *
516401 *  6532 interface
517402 *
518403 *************************************/
519404
520static void r6532_irq(device_t *device, int state)
405void exidy_sound_device::r6532_irq(int state)
521406{
522   exidy_sound_state *sndstate = get_safe_token(device);
523   sndstate->m_riot_irq_state = (state == ASSERT_LINE) ? 1 : 0;
524   update_irq_state(device, 0);
407   m_riot_irq_state = (state == ASSERT_LINE) ? 1 : 0;
408   update_irq_state(0);
525409}
526410
527411
528static WRITE8_DEVICE_HANDLER( r6532_porta_w )
412WRITE8_MEMBER( exidy_sound_device::r6532_porta_w )
529413{
530   exidy_sound_state *state = get_safe_token(device);
531   if (state->m_cvsd != NULL)
414   if (m_cvsd != NULL)
532415      space.machine().device("cvsdcpu")->execute().set_input_line(INPUT_LINE_RESET, (data & 0x10) ? CLEAR_LINE : ASSERT_LINE);
533416
534   if (state->m_tms != NULL)
417   if (m_tms != NULL)
535418   {
536      logerror("(%f)%s:TMS5220 data write = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), state->m_riot->porta_out_get());
537      state->m_tms->data_w(space, 0, data);
419      logerror("(%f)%s:TMS5220 data write = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), m_riot->porta_out_get());
420      m_tms->data_w(space, 0, data);
538421   }
539422}
540423
541static READ8_DEVICE_HANDLER( r6532_porta_r )
424READ8_MEMBER( exidy_sound_device::r6532_porta_r )
542425{
543   exidy_sound_state *state = get_safe_token(device);
544   if (state->m_tms != NULL)
426   if (m_tms != NULL)
545427   {
546      logerror("(%f)%s:TMS5220 status read = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), state->m_tms->status_r(space, 0));
547      return state->m_tms->status_r(space, 0);
428      logerror("(%f)%s:TMS5220 status read = %02X\n", space.machine().time().as_double(), space.machine().describe_context(), m_tms->status_r(space, 0));
429      return m_tms->status_r(space, 0);
548430   }
549431   else
550432      return 0xff;
551433}
552434
553static WRITE8_DEVICE_HANDLER( r6532_portb_w )
435WRITE8_MEMBER( exidy_sound_device::r6532_portb_w )
554436{
555   exidy_sound_state *state = get_safe_token(device);
556   if (state->m_tms != NULL)
437   if (m_tms != NULL)
557438   {
558      state->m_tms->rsq_w(data & 0x01);
559      state->m_tms->wsq_w((data >> 1) & 0x01);
439      m_tms->rsq_w(data & 0x01);
440      m_tms->wsq_w((data >> 1) & 0x01);
560441   }
561442}
562443
563444
564static READ8_DEVICE_HANDLER( r6532_portb_r )
445READ8_MEMBER( exidy_sound_device::r6532_portb_r )
565446{
566   exidy_sound_state *state = get_safe_token(device);
567   UINT8 newdata = state->m_riot->portb_in_get();
568   if (state->m_tms != NULL)
447   UINT8 newdata = m_riot->portb_in_get();
448   if (m_tms != NULL)
569449   {
570450      newdata &= ~0x0c;
571      if (state->m_tms->readyq_r()) newdata |= 0x04;
572      if (state->m_tms->intq_r()) newdata |= 0x08;
451      if (m_tms->readyq_r()) newdata |= 0x04;
452      if (m_tms->intq_r()) newdata |= 0x08;
573453   }
574454   return newdata;
575455}
r24635r24636
577457
578458static const riot6532_interface r6532_interface =
579459{
580   DEVCB_DEVICE_HANDLER("custom", r6532_porta_r),  /* port A read handler */
581   DEVCB_DEVICE_HANDLER("custom", r6532_portb_r),  /* port B read handler */
582   DEVCB_DEVICE_HANDLER("custom", r6532_porta_w),  /* port A write handler */
583   DEVCB_DEVICE_HANDLER("custom", r6532_portb_w),  /* port B write handler */
584   DEVCB_DEVICE_LINE("custom", r6532_irq)          /* IRQ callback */
460   DEVCB_DEVICE_MEMBER("custom", exidy_sound_device, r6532_porta_r),  /* port A read handler */
461   DEVCB_DEVICE_MEMBER("custom", exidy_sound_device, r6532_portb_r),  /* port B read handler */
462   DEVCB_DEVICE_MEMBER("custom", exidy_sound_device, r6532_porta_w),  /* port A write handler */
463   DEVCB_DEVICE_MEMBER("custom", exidy_sound_device, r6532_portb_w),  /* port B write handler */
464   DEVCB_DEVICE_LINE_MEMBER("custom", exidy_sound_device, r6532_irq)          /* IRQ callback */
585465};
586466
587467
r24635r24636
593473 *************************************/
594474
595475
596static void sh8253_register_state_globals(device_t *device)
476void exidy_sound_device::sh8253_register_state_globals()
597477{
598   exidy_sound_state *state = get_safe_token(device);
599
600   device->save_item(NAME(state->m_sh8253_timer[0].clstate));
601   device->save_item(NAME(state->m_sh8253_timer[0].enable));
602   device->save_item(NAME(state->m_sh8253_timer[0].count));
603   device->save_item(NAME(state->m_sh8253_timer[0].step));
604   device->save_item(NAME(state->m_sh8253_timer[0].fraction));
605   device->save_item(NAME(state->m_sh8253_timer[1].clstate));
606   device->save_item(NAME(state->m_sh8253_timer[1].enable));
607   device->save_item(NAME(state->m_sh8253_timer[1].count));
608   device->save_item(NAME(state->m_sh8253_timer[1].step));
609   device->save_item(NAME(state->m_sh8253_timer[1].fraction));
610   device->save_item(NAME(state->m_sh8253_timer[2].clstate));
611   device->save_item(NAME(state->m_sh8253_timer[2].enable));
612   device->save_item(NAME(state->m_sh8253_timer[2].count));
613   device->save_item(NAME(state->m_sh8253_timer[2].step));
614   device->save_item(NAME(state->m_sh8253_timer[2].fraction));
478   save_item(NAME(m_sh8253_timer[0].clstate));
479   save_item(NAME(m_sh8253_timer[0].enable));
480   save_item(NAME(m_sh8253_timer[0].count));
481   save_item(NAME(m_sh8253_timer[0].step));
482   save_item(NAME(m_sh8253_timer[0].fraction));
483   save_item(NAME(m_sh8253_timer[1].clstate));
484   save_item(NAME(m_sh8253_timer[1].enable));
485   save_item(NAME(m_sh8253_timer[1].count));
486   save_item(NAME(m_sh8253_timer[1].step));
487   save_item(NAME(m_sh8253_timer[1].fraction));
488   save_item(NAME(m_sh8253_timer[2].clstate));
489   save_item(NAME(m_sh8253_timer[2].enable));
490   save_item(NAME(m_sh8253_timer[2].count));
491   save_item(NAME(m_sh8253_timer[2].step));
492   save_item(NAME(m_sh8253_timer[2].fraction));
615493}
616494
617495/*************************************
r24635r24636
620498 *
621499 *************************************/
622500
623static WRITE8_DEVICE_HANDLER( exidy_sh8253_w )
501WRITE8_MEMBER( exidy_sound_device::sh8253_w )
624502{
625   exidy_sound_state *state = get_safe_token(device);
626503   int chan;
627504
628   state->m_stream->update();
505   m_stream->update();
629506
630507   switch (offset)
631508   {
r24635r24636
633510      case 1:
634511      case 2:
635512         chan = offset;
636         if (!state->m_sh8253_timer[chan].clstate)
513         if (!m_sh8253_timer[chan].clstate)
637514         {
638            state->m_sh8253_timer[chan].clstate = 1;
639            state->m_sh8253_timer[chan].count = (state->m_sh8253_timer[chan].count & 0xff00) | (data & 0x00ff);
515            m_sh8253_timer[chan].clstate = 1;
516            m_sh8253_timer[chan].count = (m_sh8253_timer[chan].count & 0xff00) | (data & 0x00ff);
640517         }
641518         else
642519         {
643            state->m_sh8253_timer[chan].clstate = 0;
644            state->m_sh8253_timer[chan].count = (state->m_sh8253_timer[chan].count & 0x00ff) | ((data << 8) & 0xff00);
645            if (state->m_sh8253_timer[chan].count)
646               state->m_sh8253_timer[chan].step = state->m_freq_to_step * (double)SH8253_CLOCK / (double)state->m_sh8253_timer[chan].count;
520            m_sh8253_timer[chan].clstate = 0;
521            m_sh8253_timer[chan].count = (m_sh8253_timer[chan].count & 0x00ff) | ((data << 8) & 0xff00);
522            if (m_sh8253_timer[chan].count)
523               m_sh8253_timer[chan].step = m_freq_to_step * (double)SH8253_CLOCK / (double)m_sh8253_timer[chan].count;
647524            else
648               state->m_sh8253_timer[chan].step = 0;
525               m_sh8253_timer[chan].step = 0;
649526         }
650527         break;
651528
652529      case 3:
653530         chan = (data & 0xc0) >> 6;
654         state->m_sh8253_timer[chan].enable = ((data & 0x0e) != 0);
531         m_sh8253_timer[chan].enable = ((data & 0x0e) != 0);
655532         break;
656533   }
657534}
658535
659536
660static READ8_DEVICE_HANDLER( exidy_sh8253_r )
537READ8_MEMBER( exidy_sound_device::sh8253_r )
661538{
662539   logerror("8253(R): %x\n",offset);
663540
r24635r24636
672549 *
673550 *************************************/
674551
675READ8_DEVICE_HANDLER( exidy_sh6840_r )
552READ8_MEMBER( exidy_sound_device::sh6840_r )
676553{
677   exidy_sound_state *state = get_safe_token(device);
678
679554   /* force an update of the stream */
680   state->m_stream->update();
555   m_stream->update();
681556
682557   switch (offset)
683558   {
r24635r24636
686561      return 0;
687562      /* offset 1 reads the status register: bits 2 1 0 correspond to ints on channels 2,1,0, and bit 7 is an 'OR' of bits 2,1,0 */
688563      case 1:
689      logerror("%04X:exidy_sh6840_r - unexpected read, status register is TODO!\n", state->m_maincpu->pc());
564      logerror("%04X:exidy_sh6840_r - unexpected read, status register is TODO!\n", m_maincpu->pc());
690565      return 0;
691566      /* offsets 2,4,6 read channel 0,1,2 MSBs and latch the LSB*/
692567      case 2: case 4: case 6:
693      state->m_sh6840_LSB_latch = state->m_sh6840_timer[((offset>>1)-1)].counter.b.l;
694      return state->m_sh6840_timer[((offset>>1)-1)].counter.b.h;
568      m_sh6840_LSB_latch = m_sh6840_timer[((offset>>1)-1)].counter.b.l;
569      return m_sh6840_timer[((offset>>1)-1)].counter.b.h;
695570      /* offsets 3,5,7 read the LSB latch*/
696571      default: /* case 3,5,7 */
697      return state->m_sh6840_LSB_latch;
572      return m_sh6840_LSB_latch;
698573   }
699574}
700575
701576
702WRITE8_DEVICE_HANDLER( exidy_sh6840_w )
577WRITE8_MEMBER( exidy_sound_device::sh6840_w )
703578{
704   exidy_sound_state *state = get_safe_token(device);
705   struct sh6840_timer_channel *sh6840_timer = state->m_sh6840_timer;
579   struct sh6840_timer_channel *sh6840_timer = m_sh6840_timer;
706580
707581   /* force an update of the stream */
708   state->m_stream->update();
582   m_stream->update();
709583
710584   switch (offset)
711585   {
r24635r24636
734608      case 2:
735609      case 4:
736610      case 6:
737         state->m_sh6840_MSB_latch = data;
611         m_sh6840_MSB_latch = data;
738612         break;
739613
740614      /* offsets 3/5/7 write to the LSB controls */
r24635r24636
744618      {
745619         /* latch the timer value */
746620         int ch = (offset - 3) / 2;
747         sh6840_timer[ch].timer = (state->m_sh6840_MSB_latch << 8) | (data & 0xff);
621         sh6840_timer[ch].timer = (m_sh6840_MSB_latch << 8) | (data & 0xff);
748622
749623         /* if CR4 is clear, the value is loaded immediately */
750624         if (!(sh6840_timer[ch].cr & 0x10))
r24635r24636
762636 *
763637 *************************************/
764638
765WRITE8_DEVICE_HANDLER( exidy_sfxctrl_w )
639WRITE8_MEMBER( exidy_sound_device::sfxctrl_w )
766640{
767   exidy_sound_state *state = get_safe_token(device);
641   m_stream->update();
768642
769   state->m_stream->update();
770
771643   switch (offset)
772644   {
773645      case 0:
774         state->m_sfxctrl = data;
646         m_sfxctrl = data;
775647         break;
776648
777649      case 1:
778650      case 2:
779651      case 3:
780         state->m_sh6840_volume[offset - 1] = ((data & 7) * BASE_VOLUME) / 7;
652         m_sh6840_volume[offset - 1] = ((data & 7) * BASE_VOLUME) / 7;
781653         break;
782654   }
783655}
r24635r24636
790662 *
791663 *************************************/
792664
793static WRITE8_DEVICE_HANDLER( exidy_sound_filter_w )
665WRITE8_MEMBER( venture_sound_device::filter_w )
794666{
795667   logerror("exidy_sound_filter_w = %02X\n", data);
796668}
r24635r24636
833705   DEVCB_DEVICE_LINE_MEMBER("pia0", pia6821_device, cb1_w),        /* line CA2 out */
834706   DEVCB_DEVICE_LINE_MEMBER("pia0", pia6821_device, ca1_w),        /* port CB2 out */
835707   DEVCB_NULL,     /* IRQA */
836   DEVCB_DEVICE_LINE("custom", update_irq_state)       /* IRQB */
708   DEVCB_DEVICE_LINE_MEMBER("custom", exidy_sound_device, update_irq_state)       /* IRQB */
837709};
838710
839711
840static DEVICE_START( venture_common_sh_start )
841{
842   exidy_sound_state *state = get_safe_token(device);
843   running_machine &machine = device->machine();
844
845   DEVICE_START_CALL(common_sh_start);
846
847   state->m_riot = machine.device<riot6532_device>("riot");
848
849   state->m_has_sh8253  = TRUE;
850   state->m_tms = NULL;
851   state->m_pia1 = device->machine().device<pia6821_device>("pia1");
852
853   /* determine which sound hardware is installed */
854   state->m_cvsd = device->machine().device<hc55516_device>("cvsd");
855
856   /* 8253 */
857   state->m_freq_to_step = (double)(1 << 24) / (double)SH8253_CLOCK;
858
859   device->save_item(NAME(state->m_riot_irq_state));
860   sh8253_register_state_globals(device);
861}
862
863
864static DEVICE_START( venture_sound )
865{
866   DEVICE_START_CALL(venture_common_sh_start);
867}
868
869
870static DEVICE_RESET( venture_sound )
871{
872   exidy_sound_state *state = get_safe_token(device);
873
874   DEVICE_RESET_CALL(common_sh_reset);
875
876   /* PIA */
877   device->machine().device("pia0")->reset();
878   device->machine().device("pia1")->reset();
879
880   /* 6532 */
881   state->m_riot->reset();
882
883   /* 8253 */
884   memset(state->m_sh8253_timer, 0, sizeof(state->m_sh8253_timer));
885}
886
887
888712const device_type EXIDY_VENTURE = &device_creator<venture_sound_device>;
889713
890714venture_sound_device::venture_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
r24635r24636
908732
909733void venture_sound_device::device_start()
910734{
911   DEVICE_START_NAME( venture_sound )(this);
735   common_sh_start();
736
737   m_riot = machine().device<riot6532_device>("riot");
738
739   m_has_sh8253  = TRUE;
740   m_tms = NULL;
741   m_pia0 = machine().device<pia6821_device>("pia0");
742   m_pia1 = machine().device<pia6821_device>("pia1");
743
744   /* determine which sound hardware is installed */
745   m_cvsd = machine().device<hc55516_device>("cvsd");
746
747   /* 8253 */
748   m_freq_to_step = (double)(1 << 24) / (double)SH8253_CLOCK;
749
750   save_item(NAME(m_riot_irq_state));
751   sh8253_register_state_globals();
912752}
913753
914754//-------------------------------------------------
r24635r24636
917757
918758void venture_sound_device::device_reset()
919759{
920   DEVICE_RESET_NAME( venture_sound )(this);
760   common_sh_reset();
761
762   /* PIA */
763   //machine().device("pia0")->reset();
764   m_pia0->reset();
765   //machine().device("pia1")->reset();
766   m_pia1->reset();
767   
768   /* 6532 */
769   m_riot->reset();
770
771   /* 8253 */
772   memset(m_sh8253_timer, 0, sizeof(m_sh8253_timer));
921773}
922774
923775//-------------------------------------------------
r24635r24636
926778
927779void venture_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
928780{
929   // should never get here
930   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
781   exidy_sound_device::sound_stream_update(stream, inputs, outputs, samples);
931782}
932783
933784
r24635r24636
938789   AM_RANGE(0x0000, 0x007f) AM_MIRROR(0x0780) AM_RAM
939790   AM_RANGE(0x0800, 0x087f) AM_MIRROR(0x0780) AM_DEVREADWRITE("riot", riot6532_device, read, write)
940791   AM_RANGE(0x1000, 0x1003) AM_MIRROR(0x07fc) AM_DEVREADWRITE("pia1", pia6821_device, read, write)
941   AM_RANGE(0x1800, 0x1803) AM_MIRROR(0x07fc) AM_DEVREADWRITE_LEGACY("custom", exidy_sh8253_r, exidy_sh8253_w)
942   AM_RANGE(0x2000, 0x27ff) AM_DEVWRITE_LEGACY("custom", exidy_sound_filter_w)
943   AM_RANGE(0x2800, 0x2807) AM_MIRROR(0x07f8) AM_DEVREADWRITE_LEGACY("custom", exidy_sh6840_r, exidy_sh6840_w)
944   AM_RANGE(0x3000, 0x3003) AM_MIRROR(0x07fc) AM_DEVWRITE_LEGACY("custom", exidy_sfxctrl_w)
792   AM_RANGE(0x1800, 0x1803) AM_MIRROR(0x07fc) AM_DEVREADWRITE("custom", venture_sound_device, sh8253_r, sh8253_w)
793   AM_RANGE(0x2000, 0x27ff) AM_DEVWRITE("custom", venture_sound_device, filter_w)
794   AM_RANGE(0x2800, 0x2807) AM_MIRROR(0x07f8) AM_DEVREADWRITE("custom", venture_sound_device, sh6840_r, sh6840_w)
795   AM_RANGE(0x3000, 0x3003) AM_MIRROR(0x07fc) AM_DEVWRITE("custom", venture_sound_device, sfxctrl_w)
945796   AM_RANGE(0x5800, 0x7fff) AM_ROM
946797ADDRESS_MAP_END
947798
r24635r24636
970821 *
971822 *************************************/
972823
973static WRITE8_DEVICE_HANDLER( mtrap_voiceio_w )
824WRITE8_MEMBER( venture_sound_device::mtrap_voiceio_w )
974825{
975   exidy_sound_state *state = get_safe_token(device);
976
977826   if (!(offset & 0x10))
978      state->m_cvsd->digit_w(data & 1);
827      m_cvsd->digit_w(data & 1);
979828
980829   if (!(offset & 0x20))
981      state->m_riot->portb_in_set(data & 1, 0xff);
830      m_riot->portb_in_set(data & 1, 0xff);
982831}
983832
984833
985static READ8_DEVICE_HANDLER( mtrap_voiceio_r )
834READ8_MEMBER( venture_sound_device::mtrap_voiceio_r )
986835{
987   exidy_sound_state *state = get_safe_token(device);
988
989836   if (!(offset & 0x80))
990837   {
991      UINT8 porta = state->m_riot->porta_out_get();
838      UINT8 porta = m_riot->porta_out_get();
992839      UINT8 data = (porta & 0x06) >> 1;
993840      data |= (porta & 0x01) << 2;
994841      data |= (porta & 0x08);
r24635r24636
996843   }
997844
998845   if (!(offset & 0x40))
999      return state->m_cvsd->clock_state_r() << 7;
846      return m_cvsd->clock_state_r() << 7;
1000847
1001848   return 0;
1002849}
r24635r24636
1010857
1011858static ADDRESS_MAP_START( cvsd_iomap, AS_IO, 8, driver_device )
1012859   ADDRESS_MAP_GLOBAL_MASK(0xff)
1013   AM_RANGE(0x00, 0xff) AM_DEVREADWRITE_LEGACY("custom", mtrap_voiceio_r, mtrap_voiceio_w)
860   AM_RANGE(0x00, 0xff) AM_DEVREADWRITE("custom", venture_sound_device, mtrap_voiceio_r, mtrap_voiceio_w)
1014861ADDRESS_MAP_END
1015862
1016863
r24635r24636
1038885
1039886
1040887
1041READ8_DEVICE_HANDLER( victory_sound_response_r )
888READ8_MEMBER( victory_sound_device::response_r )
1042889{
1043   exidy_sound_state *state = get_safe_token(device);
1044   UINT8 ret = state->m_pia1->b_output();
890   UINT8 ret = m_pia1->b_output();
1045891
1046   if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound response read = %02X\n", state->m_maincpu->pcbase(), ret);
892   if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound response read = %02X\n", m_maincpu->pcbase(), ret);
1047893
1048   state->m_pia1->cb1_w(0);
894   m_pia1->cb1_w(0);
1049895
1050896   return ret;
1051897}
1052898
1053899
1054READ8_DEVICE_HANDLER( victory_sound_status_r )
900READ8_MEMBER( victory_sound_device::status_r )
1055901{
1056   exidy_sound_state *state = get_safe_token(device);
1057   UINT8 ret = (state->m_pia1->ca1_r() << 7) | (state->m_pia1->cb1_r() << 6);
902   UINT8 ret = (m_pia1->ca1_r() << 7) | (m_pia1->cb1_r() << 6);
1058903
1059   if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound status read = %02X\n", state->m_maincpu->pcbase(), ret);
904   if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound status read = %02X\n", m_maincpu->pcbase(), ret);
1060905
1061906   return ret;
1062907}
1063908
1064909
1065static TIMER_CALLBACK( delayed_command_w )
910TIMER_CALLBACK_MEMBER( victory_sound_device::delayed_command_w )
1066911{
1067   pia6821_device *pia1 = (pia6821_device *)ptr;
1068   pia1->set_a_input(param, 0);
1069   pia1->ca1_w(0);
912   m_pia1->set_a_input(param, 0);
913   m_pia1->ca1_w(0);
1070914}
1071915
1072WRITE8_DEVICE_HANDLER( victory_sound_command_w )
916WRITE8_MEMBER( victory_sound_device::command_w )
1073917{
1074   exidy_sound_state *state = get_safe_token(device);
918   if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound command = %02X\n", m_maincpu->pcbase(), data);
1075919
1076   if (VICTORY_LOG_SOUND) logerror("%04X:!!!! Sound command = %02X\n", state->m_maincpu->pcbase(), data);
1077
1078   space.machine().scheduler().synchronize(FUNC(delayed_command_w), data, state->m_pia1);
920   space.machine().scheduler().synchronize(timer_expired_delegate(FUNC(victory_sound_device::delayed_command_w), this), data);
1079921}
1080922
1081923
1082static WRITE8_DEVICE_HANDLER( victory_sound_irq_clear_w )
924WRITE8_MEMBER( victory_sound_device::irq_clear_w )
1083925{
1084   exidy_sound_state *state = get_safe_token(device);
1085
1086926   if (VICTORY_LOG_SOUND) logerror("%s:!!!! Sound IRQ clear = %02X\n", space.machine().describe_context(), data);
1087927
1088   if (!data) state->m_pia1->ca1_w(1);
928   if (!data) m_pia1->ca1_w(1);
1089929}
1090930
1091931
1092static WRITE8_DEVICE_HANDLER( victory_main_ack_w )
932WRITE8_MEMBER( victory_sound_device::main_ack_w )
1093933{
1094   exidy_sound_state *state = get_safe_token(device);
1095
1096934   if (VICTORY_LOG_SOUND) logerror("%s:!!!! Sound Main ACK W = %02X\n", space.machine().describe_context(), data);
1097935
1098   if (state->m_victory_sound_response_ack_clk && !data)
1099      state->m_pia1->cb1_w(1);
936   if (m_victory_sound_response_ack_clk && !data)
937      m_pia1->cb1_w(1);
1100938
1101   state->m_victory_sound_response_ack_clk = data;
939   m_victory_sound_response_ack_clk = data;
1102940}
1103941
1104942
r24635r24636
1112950   DEVCB_NULL,     /* line CB2 in */
1113951   DEVCB_NULL,     /* port A out */
1114952   DEVCB_NULL,     /* port B out */
1115   DEVCB_DEVICE_HANDLER("custom", victory_sound_irq_clear_w),  /* line CA2 out */
1116   DEVCB_DEVICE_HANDLER("custom", victory_main_ack_w),         /* port CB2 out */
953   DEVCB_DEVICE_MEMBER("custom", victory_sound_device, irq_clear_w),  /* line CA2 out */
954   DEVCB_DEVICE_MEMBER("custom", victory_sound_device, main_ack_w),         /* port CB2 out */
1117955   DEVCB_NULL,     /* IRQA */
1118   DEVCB_DEVICE_LINE("custom", update_irq_state)               /* IRQB */
956   DEVCB_DEVICE_LINE_MEMBER("custom", exidy_sound_device, update_irq_state)               /* IRQB */
1119957};
1120958
1121
1122
1123static DEVICE_START( victory_sound )
1124{
1125   exidy_sound_state *state = get_safe_token(device);
1126
1127   device->save_item(NAME(state->m_victory_sound_response_ack_clk));
1128
1129   DEVICE_START_CALL(venture_common_sh_start);
1130   state->m_tms = device->machine().device<tms5220_device>("tms");
1131}
1132
1133
1134static DEVICE_RESET( victory_sound )
1135{
1136   exidy_sound_state *state = get_safe_token(device);
1137   pia6821_device *pia1 = state->m_pia1;
1138
1139   DEVICE_RESET_CALL(common_sh_reset);
1140   pia1->reset();
1141   state->m_riot->reset();
1142   memset(state->m_sh8253_timer, 0, sizeof(state->m_sh8253_timer));
1143
1144   /* the flip-flop @ F4 is reset */
1145   state->m_victory_sound_response_ack_clk = 0;
1146   pia1->cb1_w(1);
1147
1148   /* these two lines shouldn't be needed, but it avoids the log entry
1149      as the sound CPU checks port A before the main CPU ever writes to it */
1150   pia1->set_a_input(0, 0);
1151   pia1->ca1_w(1);
1152}
1153
1154
1155959const device_type EXIDY_VICTORY = &device_creator<victory_sound_device>;
1156960
1157961victory_sound_device::victory_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
1158   : exidy_sound_device(mconfig, EXIDY_VICTORY, "Exidy SFX+PSG+Speech", tag, owner, clock, "victory_sound", __FILE__)
962   : exidy_sound_device(mconfig, EXIDY_VICTORY, "Exidy SFX+PSG+Speech", tag, owner, clock, "victory_sound", __FILE__),
963   m_victory_sound_response_ack_clk(0)
1159964{
1160965}
1161966
r24635r24636
1175980
1176981void victory_sound_device::device_start()
1177982{
1178   DEVICE_START_NAME( victory_sound )(this);
983   save_item(NAME(m_victory_sound_response_ack_clk));
984
985   common_sh_start();
986
987   m_riot = machine().device<riot6532_device>("riot");
988
989   m_has_sh8253  = TRUE;
990   m_tms = NULL;
991   m_pia0 = machine().device<pia6821_device>("pia0");
992   m_pia1 = machine().device<pia6821_device>("pia1");
993
994   /* determine which sound hardware is installed */
995   m_cvsd = machine().device<hc55516_device>("cvsd");
996
997   /* 8253 */
998   m_freq_to_step = (double)(1 << 24) / (double)SH8253_CLOCK;
999
1000   save_item(NAME(m_riot_irq_state));
1001   sh8253_register_state_globals();
1002   
1003   m_tms = machine().device<tms5220_device>("tms");
11791004}
11801005
11811006//-------------------------------------------------
r24635r24636
11841009
11851010void victory_sound_device::device_reset()
11861011{
1187   DEVICE_RESET_NAME( victory_sound )(this);
1012   common_sh_reset();
1013   m_pia1->reset();
1014   m_riot->reset();
1015   memset(m_sh8253_timer, 0, sizeof(m_sh8253_timer));
1016
1017   /* the flip-flop @ F4 is reset */
1018   m_victory_sound_response_ack_clk = 0;
1019   m_pia1->cb1_w(1);
1020
1021   /* these two lines shouldn't be needed, but it avoids the log entry
1022      as the sound CPU checks port A before the main CPU ever writes to it */
1023   m_pia1->set_a_input(0, 0);
1024   m_pia1->ca1_w(1);
11881025}
11891026
11901027//-------------------------------------------------
r24635r24636
11931030
11941031void victory_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
11951032{
1196   // should never get here
1197   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
1033   exidy_sound_device::sound_stream_update(stream, inputs, outputs, samples);
11981034}
11991035
12001036
r24635r24636
12041040   AM_RANGE(0x0000, 0x00ff) AM_MIRROR(0x0f00) AM_RAM
12051041   AM_RANGE(0x1000, 0x107f) AM_MIRROR(0x0f80) AM_DEVREADWRITE("riot", riot6532_device, read, write)
12061042   AM_RANGE(0x2000, 0x2003) AM_MIRROR(0x0ffc) AM_DEVREADWRITE("pia1", pia6821_device, read, write)
1207   AM_RANGE(0x3000, 0x3003) AM_MIRROR(0x0ffc) AM_DEVREADWRITE_LEGACY("custom", exidy_sh8253_r, exidy_sh8253_w)
1043   AM_RANGE(0x3000, 0x3003) AM_MIRROR(0x0ffc) AM_DEVREADWRITE("custom", victory_sound_device, sh8253_r, sh8253_w)
12081044   AM_RANGE(0x4000, 0x4fff) AM_NOP
1209   AM_RANGE(0x5000, 0x5007) AM_MIRROR(0x0ff8) AM_DEVREADWRITE_LEGACY("custom", exidy_sh6840_r, exidy_sh6840_w)
1210   AM_RANGE(0x6000, 0x6003) AM_MIRROR(0x0ffc) AM_DEVWRITE_LEGACY("custom", exidy_sfxctrl_w)
1045   AM_RANGE(0x5000, 0x5007) AM_MIRROR(0x0ff8) AM_DEVREADWRITE("custom", victory_sound_device, sh6840_r, sh6840_w)
1046   AM_RANGE(0x6000, 0x6003) AM_MIRROR(0x0ffc) AM_DEVWRITE("custom", victory_sound_device, sfxctrl_w)
12111047   AM_RANGE(0x7000, 0xafff) AM_NOP
12121048   AM_RANGE(0xb000, 0xffff) AM_ROM
12131049ADDRESS_MAP_END
trunk/src/mame/audio/exidy.h
r24635r24636
1#include "machine/6532riot.h"
2#include "machine/6821pia.h"
3#include "sound/hc55516.h"
4#include "sound/tms5220.h"
5
6/* 6840 variables */
7struct sh6840_timer_channel
8{
9   UINT8   cr;
10   UINT8   state;
11   UINT8   leftovers;
12   UINT16  timer;
13   UINT32  clocks;
14   union
15   {
16#ifdef LSB_FIRST
17      struct { UINT8 l, h; } b;
18#else
19      struct { UINT8 h, l; } b;
20#endif
21      UINT16 w;
22   } counter;
23};
24
25struct sh8253_timer_channel
26{
27   UINT8   clstate;
28   UINT8   enable;
29   UINT16  count;
30   UINT32  step;
31   UINT32  fraction;
32};
33
134class exidy_sound_device : public device_t,
235                           public device_sound_interface
336{
r24635r24636
437public:
538   exidy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
639   exidy_sound_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);
7   ~exidy_sound_device() { global_free(m_token); }
40   ~exidy_sound_device() {}
841
9   // access to legacy token
10   void *token() const { assert(m_token != NULL); return m_token; }
42   DECLARE_READ8_MEMBER( sh6840_r );
43   DECLARE_WRITE8_MEMBER( sh6840_w );
44   DECLARE_WRITE8_MEMBER( sfxctrl_w );
45   
46   DECLARE_WRITE_LINE_MEMBER( update_irq_state );
47   
48   DECLARE_WRITE8_MEMBER( r6532_porta_w );
49   DECLARE_READ8_MEMBER( r6532_porta_r );
50   DECLARE_WRITE8_MEMBER( r6532_portb_w );
51   DECLARE_READ8_MEMBER( r6532_portb_r );
52   void r6532_irq(int state);
53   
54   DECLARE_WRITE8_MEMBER( sh8253_w );
55   DECLARE_READ8_MEMBER( sh8253_r );
56   
1157protected:
1258   // device-level overrides
1359   virtual void device_config_complete();
1460   virtual void device_start();
1561   virtual void device_reset();
62   
63   void common_sh_start();
64   void common_sh_reset();
65   
66   void sh6840_register_state_globals();
67   void sh8253_register_state_globals();
1668
1769   // sound stream update overrides
1870   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
71   
72   cpu_device *m_maincpu;
73   
74   /* 6532 variables */
75   riot6532_device *m_riot;
76   
77   /* IRQ variable */
78   UINT8 m_riot_irq_state;
79   
80   /* 8253 variables */
81   int m_has_sh8253;
82   struct sh8253_timer_channel m_sh8253_timer[3];
83   
84   /* 5220/CVSD variables */
85   hc55516_device *m_cvsd;
86   tms5220_device *m_tms;
87   pia6821_device *m_pia0;
88   pia6821_device *m_pia1;
89   
90   /* sound streaming variables */
91   sound_stream *m_stream;
92   double m_freq_to_step;
93     
1994private:
2095   // internal state
21   void *m_token;
96   struct sh6840_timer_channel m_sh6840_timer[3];
97   INT16 m_sh6840_volume[3];
98   UINT8 m_sh6840_MSB_latch;
99   UINT8 m_sh6840_LSB_latch;
100   UINT8 m_sh6840_LFSR_oldxor;
101   UINT32 m_sh6840_LFSR_0;
102   UINT32 m_sh6840_LFSR_1;
103   UINT32 m_sh6840_LFSR_2;
104   UINT32 m_sh6840_LFSR_3;
105   UINT32 m_sh6840_clocks_per_sample;
106   UINT32 m_sh6840_clock_count;
107
108   UINT8 m_sfxctrl;
109
110   inline int sh6840_update_noise(int clocks);
22111};
23112
24113extern const device_type EXIDY;
r24635r24636
27116{
28117public:
29118   venture_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
119   
120   DECLARE_WRITE8_MEMBER( mtrap_voiceio_w );
121   DECLARE_READ8_MEMBER( mtrap_voiceio_r );
122   
123   DECLARE_WRITE8_MEMBER( filter_w );
124   
30125protected:
31126   // device-level overrides
32127   virtual void device_config_complete();
r24635r24636
35130
36131   // sound stream update overrides
37132   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
133   
38134private:
39135   // internal state
40136};
r24635r24636
45141{
46142public:
47143   victory_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
144   
145   DECLARE_READ8_MEMBER( response_r );
146   DECLARE_READ8_MEMBER( status_r );
147   DECLARE_WRITE8_MEMBER( command_w );
148   DECLARE_WRITE8_MEMBER( irq_clear_w );
149   DECLARE_WRITE8_MEMBER( main_ack_w );
150   
48151protected:
49152   // device-level overrides
50153   virtual void device_config_complete();
r24635r24636
53156
54157   // sound stream update overrides
55158   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
159   
56160private:
57161   // internal state
162   UINT8 m_victory_sound_response_ack_clk; /* 7474 @ F4 */
163   
164   TIMER_CALLBACK_MEMBER( delayed_command_w );   
58165};
59166
60167extern const device_type EXIDY_VICTORY;
61168
62
63DECLARE_READ8_DEVICE_HANDLER( exidy_sh6840_r );
64DECLARE_WRITE8_DEVICE_HANDLER( exidy_sh6840_w );
65DECLARE_WRITE8_DEVICE_HANDLER( exidy_sfxctrl_w );
66
67169MACHINE_CONFIG_EXTERN( venture_audio );
68170
69171MACHINE_CONFIG_EXTERN( mtrap_cvsd_audio );
70172
71173MACHINE_CONFIG_EXTERN( victory_audio );
72DECLARE_READ8_DEVICE_HANDLER( victory_sound_response_r );
73DECLARE_READ8_DEVICE_HANDLER( victory_sound_status_r );
74DECLARE_WRITE8_DEVICE_HANDLER( victory_sound_command_w );
trunk/src/emu/sound/s14001a.c
r24635r24636
240240
241241#include "emu.h"
242242#include "s14001a.h"
243#include "devlegcy.h"
244243
245struct S14001AChip
246{
247   sound_stream * stream;
248244
249   UINT8 WordInput; // value on word input bus
250   UINT8 LatchedWord; // value latched from input bus
251   UINT16 SyllableAddress; // address read from word table
252   UINT16 PhoneAddress; // starting/current phone address from syllable table
253   UINT8 PlayParams; // playback parameters from syllable table
254   UINT8 PhoneOffset; // offset within phone
255   UINT8 LengthCounter; // 4-bit counter which holds the inverted length of the word in phones, leftshifted by 1
256   UINT8 RepeatCounter; // 3-bit counter which holds the inverted number of repeats per phone, leftshifted by 1
257   UINT8 OutputCounter; // 2-bit counter to determine forward/backward and output/silence state.
258   UINT8 machineState; // chip state machine state
259   UINT8 nextstate; // chip state machine's new state
260   UINT8 laststate; // chip state machine's previous state, needed for mirror increment masking
261   UINT8 resetState; // reset line state
262   UINT8 oddeven; // odd versus even cycle toggle
263   UINT8 GlobalSilenceState; // same as above but for silent syllables instead of silent portions of mirrored syllables
264   UINT8 OldDelta; // 2-bit old delta value
265   UINT8 DACOutput; // 4-bit DAC Accumulator/output
266   UINT8 audioout; // filtered audio output
267   UINT8 *SpeechRom; // array to hold rom contents, mame will not need this, will use a pointer
268   INT16 filtervals[8];
269   UINT8 VSU1000_amp; // amplitude setting on VSU-1000 board
270};
271
272INLINE S14001AChip *get_safe_token(device_t *device)
273{
274   assert(device != NULL);
275   assert(device->type() == S14001A);
276   return (S14001AChip *)downcast<s14001a_device *>(device)->token();
277}
278
279
280245//#define DEBUGSTATE
281246
282247#define SILENCE 0x7 // value output when silent
283248#define ALTFLAG 0xFF // value to tell renderer that this frame's output is the average of the 8 prior frames and not directly used.
284249
285#define LASTSYLLABLE ((chip->PlayParams & 0x80)>>7)
286#define MIRRORMODE ((chip->PlayParams & 0x40)>>6)
287#define SILENCEFLAG ((chip->PlayParams & 0x20)>>5)
288#define LENGTHCOUNT ((chip->PlayParams & 0x1C)>>1) // remember: its 4 bits and the bottom bit is always zero!
289#define REPEATCOUNT ((chip->PlayParams<<1)&0x6) // remember: its 3 bits and the bottom bit is always zero!
290#define LOCALSILENCESTATE ((chip->OutputCounter & 0x2) && (MIRRORMODE)) // 1 when silent output, 0 when DAC output.
250#define LASTSYLLABLE ((m_PlayParams & 0x80)>>7)
251#define MIRRORMODE ((m_PlayParams & 0x40)>>6)
252#define SILENCEFLAG ((m_PlayParams & 0x20)>>5)
253#define LENGTHCOUNT ((m_PlayParams & 0x1C)>>1) // remember: its 4 bits and the bottom bit is always zero!
254#define REPEATCOUNT ((m_PlayParams<<1)&0x6) // remember: its 3 bits and the bottom bit is always zero!
255#define LOCALSILENCESTATE ((m_OutputCounter & 0x2) && (MIRRORMODE)) // 1 when silent output, 0 when DAC output.
291256
292257static const INT8 DeltaTable[4][4] =
293258{
r24635r24636
298263};
299264
300265#ifdef ACCURATE_SQUEAL
301static INT16 audiofilter(S14001AChip *chip) /* rewrite me to better match the real filter! */
266INT16 s14001a_device::audiofilter() /* rewrite me to better match the real filter! */
302267{
303268   UINT8 temp1;
304269      INT16 temp2 = 0;
305270   /* mean averaging filter! 1/n exponential *would* be somewhat better, but I'm lazy... */
306   for (temp1 = 0; temp1 < 8; temp1++) { temp2 += chip->filtervals[temp1]; }
271   for (temp1 = 0; temp1 < 8; temp1++) { temp2 += m_filtervals[temp1]; }
307272   temp2 >>= 3;
308273   return temp2;
309274}
310275
311static void shiftIntoFilter(S14001AChip *chip, INT16 inputvalue)
276void s14001a_device::shiftIntoFilter(INT16 inputvalue)
312277{
313278   UINT8 temp1;
314279   for (temp1 = 7; temp1 > 0; temp1--)
315280   {
316      chip->filtervals[temp1] = chip->filtervals[(temp1 - 1)];
281      m_filtervals[temp1] = m_filtervals[(temp1 - 1)];
317282   }
318   chip->filtervals[0] = inputvalue;
283   m_filtervals[0] = inputvalue;
319284}
320285#endif
321286
322static void PostPhoneme(S14001AChip *chip) /* figure out what the heck to do after playing a phoneme */
287void s14001a_device::PostPhoneme() /* figure out what the heck to do after playing a phoneme */
323288{
324289#ifdef DEBUGSTATE
325290   fprintf(stderr,"0: entered PostPhoneme\n");
326291#endif
327   chip->RepeatCounter++; // increment the repeat counter
328   chip->OutputCounter++; // increment the output counter
292   m_RepeatCounter++; // increment the repeat counter
293   m_OutputCounter++; // increment the output counter
329294   if (MIRRORMODE) // if mirroring is enabled
330295   {
331296#ifdef DEBUGSTATE
332297      fprintf(stderr,"1: MIRRORMODE was on\n");
333298#endif
334      if (chip->RepeatCounter == 0x8) // exceeded 3 bits?
299      if (m_RepeatCounter == 0x8) // exceeded 3 bits?
335300      {
336301#ifdef DEBUGSTATE
337302         fprintf(stderr,"2: RepeatCounter was == 8\n");
338303#endif
339304         // reset repeat counter, increment length counter
340305         // but first check if lowest bit is set
341         chip->RepeatCounter = REPEATCOUNT; // reload repeat counter with reload value
342         if (chip->LengthCounter & 0x1) // if low bit is 1 (will carry after increment)
306         m_RepeatCounter = REPEATCOUNT; // reload repeat counter with reload value
307         if (m_LengthCounter & 0x1) // if low bit is 1 (will carry after increment)
343308         {
344309#ifdef DEBUGSTATE
345310            fprintf(stderr,"3: LengthCounter's low bit was 1\n");
346311#endif
347            chip->PhoneAddress+=8; // go to next phone in this syllable
312            m_PhoneAddress+=8; // go to next phone in this syllable
348313         }
349         chip->LengthCounter++;
350         if (chip->LengthCounter == 0x10) // if Length counter carried out of 4 bits
314         m_LengthCounter++;
315         if (m_LengthCounter == 0x10) // if Length counter carried out of 4 bits
351316         {
352317#ifdef DEBUGSTATE
353318            fprintf(stderr,"3: LengthCounter overflowed\n");
354319#endif
355            chip->SyllableAddress += 2; // go to next syllable
356            chip->nextstate = LASTSYLLABLE ? 13 : 3; // if we're on the last syllable, go to end state, otherwise go and load the next syllable.
320            m_SyllableAddress += 2; // go to next syllable
321            m_nextstate = LASTSYLLABLE ? 13 : 3; // if we're on the last syllable, go to end state, otherwise go and load the next syllable.
357322         }
358323         else
359324         {
360325#ifdef DEBUGSTATE
361326            fprintf(stderr,"3: LengthCounter's low bit wasn't 1 and it didn't overflow\n");
362327#endif
363            chip->PhoneOffset = (chip->OutputCounter&1) ? 7 : 0;
364            chip->nextstate = (chip->OutputCounter&1) ? 9 : 5;
328            m_PhoneOffset = (m_OutputCounter&1) ? 7 : 0;
329            m_nextstate = (m_OutputCounter&1) ? 9 : 5;
365330         }
366331      }
367332      else // repeatcounter did NOT carry out of 3 bits so leave length counter alone
368333      {
369334#ifdef DEBUGSTATE
370         fprintf(stderr,"2: RepeatCounter is less than 8 (its actually %d)\n", chip->RepeatCounter);
335         fprintf(stderr,"2: RepeatCounter is less than 8 (its actually %d)\n", m_RepeatCounter);
371336#endif
372         chip->PhoneOffset = (chip->OutputCounter&1) ? 7 : 0;
373         chip->nextstate = (chip->OutputCounter&1) ? 9 : 5;
337         m_PhoneOffset = (m_OutputCounter&1) ? 7 : 0;
338         m_nextstate = (m_OutputCounter&1) ? 9 : 5;
374339      }
375340   }
376341   else // if mirroring is NOT enabled
r24635r24636
378343#ifdef DEBUGSTATE
379344      fprintf(stderr,"1: MIRRORMODE was off\n");
380345#endif
381      if (chip->RepeatCounter == 0x8) // exceeded 3 bits?
346      if (m_RepeatCounter == 0x8) // exceeded 3 bits?
382347      {
383348#ifdef DEBUGSTATE
384349         fprintf(stderr,"2: RepeatCounter was == 8\n");
385350#endif
386351         // reset repeat counter, increment length counter
387         chip->RepeatCounter = REPEATCOUNT; // reload repeat counter with reload value
388         chip->LengthCounter++;
389         if (chip->LengthCounter == 0x10) // if Length counter carried out of 4 bits
352         m_RepeatCounter = REPEATCOUNT; // reload repeat counter with reload value
353         m_LengthCounter++;
354         if (m_LengthCounter == 0x10) // if Length counter carried out of 4 bits
390355         {
391356#ifdef DEBUGSTATE
392357            fprintf(stderr,"3: LengthCounter overflowed\n");
393358#endif
394            chip->SyllableAddress += 2; // go to next syllable
395            chip->nextstate = LASTSYLLABLE ? 13 : 3; // if we're on the last syllable, go to end state, otherwise go and load the next syllable.
359            m_SyllableAddress += 2; // go to next syllable
360            m_nextstate = LASTSYLLABLE ? 13 : 3; // if we're on the last syllable, go to end state, otherwise go and load the next syllable.
396361#ifdef DEBUGSTATE
397            fprintf(stderr,"nextstate is now %d\n", chip->nextstate); // see line below, same reason.
362            fprintf(stderr,"nextstate is now %d\n", m_nextstate); // see line below, same reason.
398363#endif
399364            return; // need a return here so we don't hit the 'nextstate = 5' line below
400365         }
401366      }
402      chip->PhoneAddress += 8; // regardless of counters, the phone address always increments in non-mirrored mode
403      chip->PhoneOffset = 0;
404      chip->nextstate = 5;
367      m_PhoneAddress += 8; // regardless of counters, the phone address always increments in non-mirrored mode
368      m_PhoneOffset = 0;
369      m_nextstate = 5;
405370   }
406371#ifdef DEBUGSTATE
407   fprintf(stderr,"nextstate is now %d\n", chip->nextstate);
372   fprintf(stderr,"nextstate is now %d\n", m_nextstate);
408373#endif
409374}
410375
411static void s14001a_clock(S14001AChip *chip) /* called once per clock */
376void s14001a_device::s14001a_clock() /* called once per clock */
412377{
413378   UINT8 CurDelta; // Current delta
414379
415380   /* on even clocks, audio output is floating, /romen is low so rom data bus is driven
416381        * on odd clocks, audio output is driven, /romen is high, state machine 2 is clocked
417382        */
418   chip->oddeven = !(chip->oddeven); // invert the clock
419   if (chip->oddeven == 0) // even clock
383   m_oddeven = !(m_oddeven); // invert the clock
384   if (m_oddeven == 0) // even clock
420385   {
421386#ifdef ACCURATE_SQUEAL
422      chip->audioout = ALTFLAG; // flag to the renderer that this output should be the average of the last 8
387      m_audioout = ALTFLAG; // flag to the renderer that this output should be the average of the last 8
423388#endif
424389      // DIGITAL INPUT *MIGHT* occur on the test pins occurs on this cycle?
425390   }
r24635r24636
427392   {
428393      // fix dac output between samples. theoretically this might be unnecessary but it would require some messy logic in state 5 on the first sample load.
429394      // Note: this behavior is NOT accurate, and needs to be fixed. see TODO.
430      if (chip->GlobalSilenceState || LOCALSILENCESTATE)
395      if (m_GlobalSilenceState || LOCALSILENCESTATE)
431396      {
432         chip->DACOutput = SILENCE;
433         chip->OldDelta = 2;
397         m_DACOutput = SILENCE;
398         m_OldDelta = 2;
434399      }
435      chip->audioout = (chip->GlobalSilenceState || LOCALSILENCESTATE) ? SILENCE : chip->DACOutput; // when either silence state is 1, output silence.
400      m_audioout = (m_GlobalSilenceState || LOCALSILENCESTATE) ? SILENCE : m_DACOutput; // when either silence state is 1, output silence.
436401      // DIGITAL OUTPUT *might* be driven onto the test pins on this cycle?
437      switch(chip->machineState) // HUUUUUGE switch statement
402      switch(m_machineState) // HUUUUUGE switch statement
438403      {
439404      case 0: // idle state
440         chip->nextstate = 0;
405         m_nextstate = 0;
441406         break;
442407      case 1: // read starting syllable high byte from word table
443         chip->SyllableAddress = 0; // clear syllable address
444         chip->SyllableAddress |= chip->SpeechRom[(chip->LatchedWord<<1)]<<4;
445         chip->nextstate = chip->resetState ? 1 : 2;
408         m_SyllableAddress = 0; // clear syllable address
409         m_SyllableAddress |= m_SpeechRom[(m_LatchedWord<<1)]<<4;
410         m_nextstate = m_resetState ? 1 : 2;
446411         break;
447412      case 2: // read starting syllable low byte from word table
448         chip->SyllableAddress |= chip->SpeechRom[(chip->LatchedWord<<1)+1]>>4;
449         chip->nextstate = 3;
413         m_SyllableAddress |= m_SpeechRom[(m_LatchedWord<<1)+1]>>4;
414         m_nextstate = 3;
450415         break;
451416      case 3: // read starting phone address
452         chip->PhoneAddress = chip->SpeechRom[chip->SyllableAddress]<<4;
453         chip->nextstate = 4;
417         m_PhoneAddress = m_SpeechRom[m_SyllableAddress]<<4;
418         m_nextstate = 4;
454419         break;
455420      case 4: // read playback parameters and prepare for play
456         chip->PlayParams = chip->SpeechRom[chip->SyllableAddress+1];
457         chip->GlobalSilenceState = SILENCEFLAG; // load phone silence flag
458         chip->LengthCounter = LENGTHCOUNT; // load length counter
459         chip->RepeatCounter = REPEATCOUNT; // load repeat counter
460         chip->OutputCounter = 0; // clear output counter and disable mirrored phoneme silence indirectly via LOCALSILENCESTATE
461         chip->PhoneOffset = 0; // set offset within phone to zero
462         chip->OldDelta = 0x2; // set old delta to 2 <- is this right?
463         chip->DACOutput = SILENCE ; // set DAC output to center/silence position
464         chip->nextstate = 5;
421         m_PlayParams = m_SpeechRom[m_SyllableAddress+1];
422         m_GlobalSilenceState = SILENCEFLAG; // load phone silence flag
423         m_LengthCounter = LENGTHCOUNT; // load length counter
424         m_RepeatCounter = REPEATCOUNT; // load repeat counter
425         m_OutputCounter = 0; // clear output counter and disable mirrored phoneme silence indirectly via LOCALSILENCESTATE
426         m_PhoneOffset = 0; // set offset within phone to zero
427         m_OldDelta = 0x2; // set old delta to 2 <- is this right?
428         m_DACOutput = SILENCE ; // set DAC output to center/silence position
429         m_nextstate = 5;
465430         break;
466431      case 5: // Play phone forward, shift = 0 (also load)
467         CurDelta = (chip->SpeechRom[(chip->PhoneAddress)+chip->PhoneOffset]&0xc0)>>6; // grab current delta from high 2 bits of high nybble
468         chip->DACOutput += DeltaTable[CurDelta][chip->OldDelta]; // send data to forward delta table and add result to accumulator
469         chip->OldDelta = CurDelta; // Move current delta to old
470         chip->nextstate = 6;
432         CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0xc0)>>6; // grab current delta from high 2 bits of high nybble
433         m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
434         m_OldDelta = CurDelta; // Move current delta to old
435         m_nextstate = 6;
471436         break;
472437      case 6: // Play phone forward, shift = 2
473         CurDelta = (chip->SpeechRom[(chip->PhoneAddress)+chip->PhoneOffset]&0x30)>>4; // grab current delta from low 2 bits of high nybble
474         chip->DACOutput += DeltaTable[CurDelta][chip->OldDelta]; // send data to forward delta table and add result to accumulator
475         chip->OldDelta = CurDelta; // Move current delta to old
476         chip->nextstate = 7;
438         CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0x30)>>4; // grab current delta from low 2 bits of high nybble
439         m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
440         m_OldDelta = CurDelta; // Move current delta to old
441         m_nextstate = 7;
477442         break;
478443      case 7: // Play phone forward, shift = 4
479         CurDelta = (chip->SpeechRom[(chip->PhoneAddress)+chip->PhoneOffset]&0xc)>>2; // grab current delta from high 2 bits of low nybble
480         chip->DACOutput += DeltaTable[CurDelta][chip->OldDelta]; // send data to forward delta table and add result to accumulator
481         chip->OldDelta = CurDelta; // Move current delta to old
482         chip->nextstate = 8;
444         CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0xc)>>2; // grab current delta from high 2 bits of low nybble
445         m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
446         m_OldDelta = CurDelta; // Move current delta to old
447         m_nextstate = 8;
483448         break;
484449      case 8: // Play phone forward, shift = 6 (increment address if needed)
485         CurDelta = chip->SpeechRom[(chip->PhoneAddress)+chip->PhoneOffset]&0x3; // grab current delta from low 2 bits of low nybble
486         chip->DACOutput += DeltaTable[CurDelta][chip->OldDelta]; // send data to forward delta table and add result to accumulator
487         chip->OldDelta = CurDelta; // Move current delta to old
488         chip->PhoneOffset++; // increment phone offset
489         if (chip->PhoneOffset == 0x8) // if we're now done this phone
450         CurDelta = m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0x3; // grab current delta from low 2 bits of low nybble
451         m_DACOutput += DeltaTable[CurDelta][m_OldDelta]; // send data to forward delta table and add result to accumulator
452         m_OldDelta = CurDelta; // Move current delta to old
453         m_PhoneOffset++; // increment phone offset
454         if (m_PhoneOffset == 0x8) // if we're now done this phone
490455         {
491456            /* call the PostPhoneme Function */
492            PostPhoneme(chip);
457            PostPhoneme();
493458         }
494459         else
495460         {
496            chip->nextstate = 5;
461            m_nextstate = 5;
497462         }
498463         break;
499464      case 9: // Play phone backward, shift = 6 (also load)
500         CurDelta = (chip->SpeechRom[(chip->PhoneAddress)+chip->PhoneOffset]&0x3); // grab current delta from low 2 bits of low nybble
501         if (chip->laststate != 8) // ignore first (bogus) dac change in mirrored backwards mode. observations and the patent show this.
465         CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0x3); // grab current delta from low 2 bits of low nybble
466         if (m_laststate != 8) // ignore first (bogus) dac change in mirrored backwards mode. observations and the patent show this.
502467         {
503            chip->DACOutput -= DeltaTable[chip->OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
468            m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
504469         }
505         chip->OldDelta = CurDelta; // Move current delta to old
506         chip->nextstate = 10;
470         m_OldDelta = CurDelta; // Move current delta to old
471         m_nextstate = 10;
507472         break;
508473      case 10: // Play phone backward, shift = 4
509         CurDelta = (chip->SpeechRom[(chip->PhoneAddress)+chip->PhoneOffset]&0xc)>>2; // grab current delta from high 2 bits of low nybble
510         chip->DACOutput -= DeltaTable[chip->OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
511         chip->OldDelta = CurDelta; // Move current delta to old
512         chip->nextstate = 11;
474         CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0xc)>>2; // grab current delta from high 2 bits of low nybble
475         m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
476         m_OldDelta = CurDelta; // Move current delta to old
477         m_nextstate = 11;
513478         break;
514479      case 11: // Play phone backward, shift = 2
515         CurDelta = (chip->SpeechRom[(chip->PhoneAddress)+chip->PhoneOffset]&0x30)>>4; // grab current delta from low 2 bits of high nybble
516         chip->DACOutput -= DeltaTable[chip->OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
517         chip->OldDelta = CurDelta; // Move current delta to old
518         chip->nextstate = 12;
480         CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0x30)>>4; // grab current delta from low 2 bits of high nybble
481         m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
482         m_OldDelta = CurDelta; // Move current delta to old
483         m_nextstate = 12;
519484         break;
520485      case 12: // Play phone backward, shift = 0 (increment address if needed)
521         CurDelta = (chip->SpeechRom[(chip->PhoneAddress)+chip->PhoneOffset]&0xc0)>>6; // grab current delta from high 2 bits of high nybble
522         chip->DACOutput -= DeltaTable[chip->OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
523         chip->OldDelta = CurDelta; // Move current delta to old
524         chip->PhoneOffset--; // decrement phone offset
525         if (chip->PhoneOffset == 0xFF) // if we're now done this phone
486         CurDelta = (m_SpeechRom[(m_PhoneAddress)+m_PhoneOffset]&0xc0)>>6; // grab current delta from high 2 bits of high nybble
487         m_DACOutput -= DeltaTable[m_OldDelta][CurDelta]; // send data to forward delta table and subtract result from accumulator
488         m_OldDelta = CurDelta; // Move current delta to old
489         m_PhoneOffset--; // decrement phone offset
490         if (m_PhoneOffset == 0xFF) // if we're now done this phone
526491         {
527492            /* call the PostPhoneme() function */
528            PostPhoneme(chip);
493            PostPhoneme();
529494         }
530495         else
531496         {
532            chip->nextstate = 9;
497            m_nextstate = 9;
533498         }
534499         break;
535500      case 13: // For those pedantic among us, consume an extra two clocks like the real chip does.
536         chip->nextstate = 0;
501         m_nextstate = 0;
537502         break;
538503      }
539504#ifdef DEBUGSTATE
540      fprintf(stderr, "Machine state is now %d, was %d, PhoneOffset is %d\n", chip->nextstate, chip->machineState, chip->PhoneOffset);
505      fprintf(stderr, "Machine state is now %d, was %d, PhoneOffset is %d\n", m_nextstate, m_machineState, m_PhoneOffset);
541506#endif
542      chip->laststate = chip->machineState;
543      chip->machineState = chip->nextstate;
507      m_laststate = m_machineState;
508      m_machineState = m_nextstate;
544509
545510         /* the dac is 4 bits wide. if a delta step forced it outside of 4 bits, mask it back over here */
546         chip->DACOutput &= 0xF;
511         m_DACOutput &= 0xF;
547512   }
548513}
549514
r24635r24636
551516   MAME glue code
552517 **************************************************************************/
553518
554static STREAM_UPDATE( s14001a_pcm_update )
519int s14001a_device::bsy_r()
555520{
556   S14001AChip *chip = (S14001AChip *)param;
557   int i;
558
559   for (i = 0; i < samples; i++)
560   {
561      s14001a_clock(chip);
562#ifdef ACCURATE_SQUEAL
563      if (chip->audioout == ALTFLAG) // input from test pins -> output
564      {
565         shiftIntoFilter(chip, audiofilter(chip)); // shift over the previous outputs and stick in audioout.
566         outputs[0][i] = audiofilter(chip)*chip->VSU1000_amp;
567      }
568      else // normal, dac-driven output
569      {
570         shiftIntoFilter(chip, ((((INT16)chip->audioout)-8)<<9)); // shift over the previous outputs and stick in audioout 4 times. note <<9 instead of <<10, to prevent clipping, and to simulate that the filtered output normally has a somewhat lower amplitude than the driven one.
571#endif
572         outputs[0][i] = ((((INT16)chip->audioout)-8)<<10)*chip->VSU1000_amp;
573#ifdef ACCURATE_SQUEAL
574      }
575#endif
576   }
577}
578
579static DEVICE_START( s14001a )
580{
581   S14001AChip *chip = get_safe_token(device);
582   int i;
583
584   chip->GlobalSilenceState = 1;
585   chip->OldDelta = 0x02;
586   chip->DACOutput = SILENCE;
587
588   for (i = 0; i < 8; i++)
589   {
590      chip->filtervals[i] = SILENCE;
591   }
592
593   chip->SpeechRom = *device->region();
594
595   chip->stream = device->machine().sound().stream_alloc(*device, 0, 1, device->clock() ? device->clock() : device->machine().sample_rate(), chip, s14001a_pcm_update);
596}
597
598int s14001a_bsy_r(device_t *device)
599{
600   S14001AChip *chip = get_safe_token(device);
601   chip->stream->update();
521   m_stream->update();
602522#ifdef DEBUGSTATE
603   fprintf(stderr,"busy state checked: %d\n",(chip->machineState != 0) );
523   fprintf(stderr,"busy state checked: %d\n",(m_machineState != 0) );
604524#endif
605   return (chip->machineState != 0);
525   return (m_machineState != 0);
606526}
607527
608void s14001a_reg_w(device_t *device, int data)
528void s14001a_device::reg_w(int data)
609529{
610   S14001AChip *chip = get_safe_token(device);
611   chip->stream->update();
612   chip->WordInput = data;
530   m_stream->update();
531   m_WordInput = data;
613532}
614533
615void s14001a_rst_w(device_t *device, int data)
534void s14001a_device::rst_w(int data)
616535{
617   S14001AChip *chip = get_safe_token(device);
618   chip->stream->update();
619   chip->LatchedWord = chip->WordInput;
620   chip->resetState = (data==1);
621   chip->machineState = chip->resetState ? 1 : chip->machineState;
536   m_stream->update();
537   m_LatchedWord = m_WordInput;
538   m_resetState = (data==1);
539   m_machineState = m_resetState ? 1 : m_machineState;
622540}
623541
624void s14001a_set_clock(device_t *device, int clock)
542void s14001a_device::set_clock(int clock)
625543{
626   S14001AChip *chip = get_safe_token(device);
627   chip->stream->set_sample_rate(clock);
544   m_stream->set_sample_rate(clock);
628545}
629546
630void s14001a_set_volume(device_t *device, int volume)
547void s14001a_device::set_volume(int volume)
631548{
632   S14001AChip *chip = get_safe_token(device);
633   chip->stream->update();
634   chip->VSU1000_amp = volume;
549   m_stream->update();
550   m_VSU1000_amp = volume;
635551}
636552
637553const device_type S14001A = &device_creator<s14001a_device>;
638554
639555s14001a_device::s14001a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
640556   : device_t(mconfig, S14001A, "S14001A", tag, owner, clock, "s14001a", __FILE__),
641      device_sound_interface(mconfig, *this)
557      device_sound_interface(mconfig, *this),
558      m_stream(NULL),
559      m_WordInput(0),
560      m_LatchedWord(0),
561      m_SyllableAddress(0),
562      m_PhoneAddress(0),
563      m_PlayParams(0),
564      m_PhoneOffset(0),
565      m_LengthCounter(0),
566      m_RepeatCounter(0),
567      m_OutputCounter(0),
568      m_machineState(0),
569      m_nextstate(0),
570      m_laststate(0),
571      m_resetState(0),
572      m_oddeven(0),
573      m_GlobalSilenceState(1),
574      m_OldDelta(0x02),
575      m_DACOutput(SILENCE),
576      m_audioout(0),
577      m_SpeechRom(NULL),
578      m_VSU1000_amp(0)
642579{
643   m_token = global_alloc_clear(S14001AChip);
644580}
645581
646582//-------------------------------------------------
r24635r24636
659595
660596void s14001a_device::device_start()
661597{
662   DEVICE_START_NAME( s14001a )(this);
598   int i;
599
600   m_GlobalSilenceState = 1;
601   m_OldDelta = 0x02;
602   m_DACOutput = SILENCE;
603
604   for (i = 0; i < 8; i++)
605   {
606      m_filtervals[i] = SILENCE;
607   }
608
609   m_SpeechRom = *region();
610
611   m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() ? clock() : machine().sample_rate(), this);
663612}
664613
665614//-------------------------------------------------
r24635r24636
668617
669618void s14001a_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
670619{
671   // should never get here
672   fatalerror("sound_stream_update called; not applicable to legacy sound devices\n");
620   int i;
621
622   for (i = 0; i < samples; i++)
623      {
624         s14001a_clock();
625   #ifdef ACCURATE_SQUEAL
626      if (m_audioout == ALTFLAG) // input from test pins -> output
627         {
628            shiftIntoFilter(chip, audiofilter(chip)); // shift over the previous outputs and stick in audioout.
629            outputs[0][i] = audiofilter(chip)*m_VSU1000_amp;
630         }
631      else // normal, dac-driven output
632         {
633            shiftIntoFilter(chip, ((((INT16)m_audioout)-8)<<9)); // shift over the previous outputs and stick in audioout 4 times. note <<9 instead of <<10, to prevent clipping, and to simulate that the filtered output normally has a somewhat lower amplitude than the driven one.
634   #endif
635            outputs[0][i] = ((((INT16)m_audioout)-8)<<10)*m_VSU1000_amp;
636   #ifdef ACCURATE_SQUEAL
637         }
638   #endif
639      }
673640}
trunk/src/emu/sound/s14001a.h
r24635r24636
44#define __S14001A_H__
55
66
7int s14001a_bsy_r(device_t *device);        /* read BUSY pin */
8void s14001a_reg_w(device_t *device, int data);     /* write to input latch */
9void s14001a_rst_w(device_t *device, int data);     /* write to RESET pin */
10void s14001a_set_clock(device_t *device, int clock);     /* set VSU-1000 clock */
11void s14001a_set_volume(device_t *device, int volume);    /* set VSU-1000 volume control */
12
137class s14001a_device : public device_t,
148                           public device_sound_interface
159{
1610public:
1711   s14001a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
18   ~s14001a_device() { global_free(m_token); }
12   ~s14001a_device() {}
1913
20   // access to legacy token
21   void *token() const { assert(m_token != NULL); return m_token; }
14   int bsy_r();        /* read BUSY pin */
15   void reg_w(int data);     /* write to input latch */
16   void rst_w(int data);     /* write to RESET pin */
17   void set_clock(int clock);     /* set VSU-1000 clock */
18   void set_volume(int volume);    /* set VSU-1000 volume control */
19
2220protected:
2321   // device-level overrides
2422   virtual void device_config_complete();
r24635r24636
2624
2725   // sound stream update overrides
2826   virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
27   
2928private:
3029   // internal state
31   void *m_token;
30   sound_stream * m_stream;
31
32   UINT8 m_WordInput; // value on word input bus
33   UINT8 m_LatchedWord; // value latched from input bus
34   UINT16 m_SyllableAddress; // address read from word table
35   UINT16 m_PhoneAddress; // starting/current phone address from syllable table
36   UINT8 m_PlayParams; // playback parameters from syllable table
37   UINT8 m_PhoneOffset; // offset within phone
38   UINT8 m_LengthCounter; // 4-bit counter which holds the inverted length of the word in phones, leftshifted by 1
39   UINT8 m_RepeatCounter; // 3-bit counter which holds the inverted number of repeats per phone, leftshifted by 1
40   UINT8 m_OutputCounter; // 2-bit counter to determine forward/backward and output/silence state.
41   UINT8 m_machineState; // chip state machine state
42   UINT8 m_nextstate; // chip state machine's new state
43   UINT8 m_laststate; // chip state machine's previous state, needed for mirror increment masking
44   UINT8 m_resetState; // reset line state
45   UINT8 m_oddeven; // odd versus even cycle toggle
46   UINT8 m_GlobalSilenceState; // same as above but for silent syllables instead of silent portions of mirrored syllables
47   UINT8 m_OldDelta; // 2-bit old delta value
48   UINT8 m_DACOutput; // 4-bit DAC Accumulator/output
49   UINT8 m_audioout; // filtered audio output
50   UINT8 *m_SpeechRom; // array to hold rom contents, mame will not need this, will use a pointer
51   INT16 m_filtervals[8];
52   UINT8 m_VSU1000_amp; // amplitude setting on VSU-1000 board
53   
54   INT16 audiofilter();
55   void shiftIntoFilter(INT16 inputvalue);
56   void PostPhoneme();
57   void s14001a_clock();
3258};
3359
3460extern const device_type S14001A;
trunk/src/mess/drivers/fidelz80.c
r24635r24636
681681
682682READ8_MEMBER( fidelz80_state::vcc_portb_r )
683683{
684   return (s14001a_bsy_r(m_speech) != 0) ? 0x80 : 0x00;
684   return (m_speech->bsy_r() != 0) ? 0x80 : 0x00;
685685}
686686
687687WRITE8_MEMBER( fidelz80_state::vcc_porta_w )
688688{
689   s14001a_set_volume(m_speech, 15); // hack, s14001a core should assume a volume of 15 unless otherwise stated...
690   s14001a_reg_w(m_speech, data & 0x3f);
691   s14001a_rst_w(m_speech, BIT(data, 7));
689   m_speech->set_volume(15); // hack, s14001a core should assume a volume of 15 unless otherwise stated...
690   m_speech->reg_w(data & 0x3f);
691   m_speech->rst_w(BIT(data, 7));
692692
693693   m_digit_data = data;
694694
r24635r24636
743743      output_set_value("low_dot", BIT(out_digit, 7));
744744   }
745745
746   s14001a_reg_w(m_speech, data & 0x3f);
746   m_speech->reg_w(data & 0x3f);
747747}
748748
749749WRITE8_MEMBER( fidelz80_state::vsc_portb_w )
r24635r24636
820820{
821821   UINT8 data = 0x00;
822822
823   if (s14001a_bsy_r(m_speech) == 0)
823   if (m_speech->bsy_r() == 0)
824824      data |= 0x10;
825825
826826   return data;
r24635r24636
830830{
831831   m_kp_matrix = (m_kp_matrix & 0xff) | ((data & 0x03)<<8);
832832
833   s14001a_set_volume(m_speech, 15); // hack, s14001a core should assume a volume of 15 unless otherwise stated...
834   s14001a_rst_w(m_speech, BIT(data, 6));
833   m_speech->set_volume(15); // hack, s14001a core should assume a volume of 15 unless otherwise stated...
834   m_speech->rst_w(BIT(data, 6));
835835}
836836
837837static Z80PIO_INTERFACE( vsc_z80pio_intf )
r24635r24636
997997WRITE8_MEMBER( fidelz80_state::bridgec_speech_w )
998998{
999999   // todo: HALT THE z80 here, and set up a callback to poll the s14001a DONE line to resume z80
1000   s14001a_set_volume(m_speech, 15); // hack, s14001a core should assume a volume of 15 unless otherwise stated...
1001   s14001a_reg_w(m_speech, data & 0x3f);
1002   s14001a_rst_w(m_speech, BIT(data, 7));
1000   m_speech->set_volume(15); // hack, s14001a core should assume a volume of 15 unless otherwise stated...
1001   m_speech->reg_w(data & 0x3f);
1002   m_speech->rst_w(BIT(data, 7));
10031003}
10041004
10051005void fidelz80_state::machine_reset()
trunk/src/mess/drivers/csc.c
r24635r24636
8787      break;
8888   }
8989
90//  s14001a_reg_w(m_speech, data & 0x3f);
90//  m_speech->reg_w(data & 0x3f);
9191
9292   // for avoid the digit flashing
9393   m_selector |= 0x80;
r24635r24636
9595
9696WRITE8_MEMBER( csc_state::pia0_pb_w )
9797{
98//  s14001a_set_volume(m_speech, 15); // hack, s14001a core should assume a volume of 15 unless otherwise stated...
99//  s14001a_rst_w(m_speech, BIT(data, 1));
98//  m_speech->set_volume(15); // hack, s14001a core should assume a volume of 15 unless otherwise stated...
99//  m_speech->rst_w(BIT(data, 1));
100100}
101101
102102READ8_MEMBER( csc_state::pia0_pb_r )
103103{
104104   UINT8 data = 0x04;
105105
106   if(s14001a_bsy_r(m_speech))
106   if(m_speech->bsy_r())
107107      data |= 0x08;
108108
109109   if (m_selector<9)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team