diff --git a/src/emu/sound/msm5232.c b/src/emu/sound/msm5232.c index 6e3d64d5281..328920ea2c1 100644 --- a/src/emu/sound/msm5232.c +++ b/src/emu/sound/msm5232.c @@ -9,76 +9,137 @@ 8 channel tone generator */ -struct VOICE { - UINT8 mode; +const device_type MSM5232 = &device_creator; - int TG_count_period; - int TG_count; - - UINT8 TG_cnt; /* 7 bits binary counter (frequency output) */ - UINT8 TG_out16; /* bit number (of TG_cnt) for 16' output */ - UINT8 TG_out8; /* bit number (of TG_cnt) for 8' output */ - UINT8 TG_out4; /* bit number (of TG_cnt) for 4' output */ - UINT8 TG_out2; /* bit number (of TG_cnt) for 2' output */ - - int egvol; - int eg_sect; - int counter; - int eg; - - UINT8 eg_arm; /* attack/release mode */ - - double ar_rate; - double dr_rate; - double rr_rate; - - int pitch; /* current pitch data */ - - int GF; -}; - - -struct msm5232_state { - sound_stream *stream; - - VOICE voi[8]; - - UINT32 EN_out16[2]; /* enable 16' output masks for both groups (0-disabled ; ~0 -enabled) */ - UINT32 EN_out8[2]; /* enable 8' output masks */ - UINT32 EN_out4[2]; /* enable 4' output masks */ - UINT32 EN_out2[2]; /* enable 2' output masks */ - - int noise_cnt; - int noise_step; - int noise_rng; - int noise_clocks; /* number of the noise_rng (output) level changes */ - - unsigned int UpdateStep; - - /* rate tables */ - double ar_tbl[8]; - double dr_tbl[16]; - - UINT8 control1; - UINT8 control2; - - int gate; /* current state of the GATE output */ - - int clock; /* chip clock in Hz */ - int rate; /* sample rate in Hz */ - - double external_capacity[8]; /* in Farads, eg 0.39e-6 = 0.36 uF (microFarads) */ - device_t *device; - devcb_resolved_write_line gate_handler;/* callback called when the GATE output pin changes state */ - -}; - - -INLINE msm5232_state *get_safe_token(device_t *device) +msm5232_device::msm5232_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MSM5232, "MSM5232", tag, owner, clock, "msm5232", __FILE__), + device_sound_interface(mconfig, *this) { - assert(device != NULL); - assert(device->type() == MSM5232); - return (msm5232_state *)downcast(device)->token(); +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void msm5232_device::device_config_complete() +{ + // inherit a copy of the static data + const msm5232_interface *intf = reinterpret_cast(static_config()); + if (intf != NULL) + *static_cast(this) = *intf; + + // or initialize to defaults if none provided + else + { + memset(&m_gate_handler_cb, 0, sizeof(m_gate_handler_cb)); + } +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void msm5232_device::device_start() +{ + int rate = clock()/CLOCK_RATE_DIVIDER; + int voicenum; + + init(clock(), rate); + + m_stream = machine().sound().stream_alloc(*this, 0, 11, rate, this); + + /* register with the save state system */ + machine().save().register_postload(save_prepost_delegate(FUNC(msm5232_device::postload), this)); + save_item(NAME(m_EN_out16)); + save_item(NAME(m_EN_out8)); + save_item(NAME(m_EN_out4)); + save_item(NAME(m_EN_out2)); + save_item(NAME(m_noise_cnt)); + save_item(NAME(m_noise_rng)); + save_item(NAME(m_noise_clocks)); + save_item(NAME(m_control1)); + save_item(NAME(m_control2)); + save_item(NAME(m_gate)); + save_item(NAME(m_chip_clock)); + save_item(NAME(m_rate)); + + /* register voice-specific data for save states */ + for (voicenum = 0; voicenum < 8; voicenum++) + { + VOICE *voice = &m_voi[voicenum]; + + save_item(NAME(voice->mode), voicenum); + save_item(NAME(voice->TG_count_period), voicenum); + save_item(NAME(voice->TG_cnt), voicenum); + save_item(NAME(voice->TG_out16), voicenum); + save_item(NAME(voice->TG_out8), voicenum); + save_item(NAME(voice->TG_out4), voicenum); + save_item(NAME(voice->TG_out2), voicenum); + save_item(NAME(voice->egvol), voicenum); + save_item(NAME(voice->eg_sect), voicenum); + save_item(NAME(voice->counter), voicenum); + save_item(NAME(voice->eg), voicenum); + save_item(NAME(voice->eg_arm), voicenum); + save_item(NAME(voice->ar_rate), voicenum); + save_item(NAME(voice->dr_rate), voicenum); + save_item(NAME(voice->pitch), voicenum); + save_item(NAME(voice->GF), voicenum); + } +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void msm5232_device::device_reset() +{ + int i; + + for (i=0; i<8; i++) + { + write(machine().driver_data()->generic_space(),i,0x80); + write(machine().driver_data()->generic_space(),i,0x00); + } + m_noise_cnt = 0; + m_noise_rng = 1; + m_noise_clocks = 0; + + m_control1 = 0; + m_EN_out16[0] = 0; + m_EN_out8[0] = 0; + m_EN_out4[0] = 0; + m_EN_out2[0] = 0; + + m_control2 = 0; + m_EN_out16[1] = 0; + m_EN_out8[1] = 0; + m_EN_out4[1] = 0; + m_EN_out2[1] = 0; + + gate_update(); +} + +//------------------------------------------------- +// device_stop - device-specific stop +//------------------------------------------------- + +void msm5232_device::device_stop() +{ + #ifdef SAVE_SAMPLE + fclose(sample[8]); +#endif +#ifdef SAVE_SEPARATE_CHANNELS + fclose(sample[0]); + fclose(sample[1]); + fclose(sample[2]); + fclose(sample[3]); + fclose(sample[4]); + fclose(sample[5]); + fclose(sample[6]); + fclose(sample[7]); +#endif } @@ -171,7 +232,7 @@ static FILE *sample[9]; -static void msm5232_init_tables( msm5232_state *chip ) +void msm5232_device::init_tables() { int i; double scale; @@ -180,14 +241,14 @@ static void msm5232_init_tables( msm5232_state *chip ) /* highest possible frequency is chipclock/13/16 (pitch data=0x57) */ /* at 2MHz : 2000000/13/16 = 9615 Hz */ - i = ((double)(1<rate) / (double)chip->clock; - chip->UpdateStep = i; + i = ((double)(1<clock, chip->rate, chip->UpdateStep); */ + m_chip_clock, m_rate, m_UpdateStep); */ - scale = ((double)chip->clock) / (double)chip->rate; - chip->noise_step = ((1<noise_step); */ + scale = ((double)m_chip_clock) / (double)m_rate; + m_noise_step = ((1<clock / 2119040.0; + double clockscale = (double)m_chip_clock / 2119040.0; double time = (ATBL[i] / 1000.0) / clockscale; /* attack time in seconds */ - chip->ar_tbl[i] = 0.50 * ( (1.0/time) / (double)chip->rate ); - /* logerror("ATBL[%i] = %20.16f time = %f s\n",i, chip->ar_tbl[i], time); */ + m_ar_tbl[i] = 0.50 * ( (1.0/time) / (double)m_rate ); + /* logerror("ATBL[%i] = %20.16f time = %f s\n",i, m_ar_tbl[i], time); */ } for (i=0; i<16; i++) { - double clockscale = (double)chip->clock / 2119040.0; + double clockscale = (double)m_chip_clock / 2119040.0; double time = (DTBL[i] / 1000.0) / clockscale; /* decay time in seconds */ - chip->dr_tbl[i] = 0.50 * ( (1.0/time) / (double)chip->rate ); - /* logerror("DTBL[%i] = %20.16f time = %f s\n",i, chip->dr_tbl[i], time); */ + m_dr_tbl[i] = 0.50 * ( (1.0/time) / (double)m_rate ); + /* logerror("DTBL[%i] = %20.16f time = %f s\n",i, m_dr_tbl[i], time); */ } } #endif @@ -216,15 +277,15 @@ static void msm5232_init_tables( msm5232_state *chip ) for (i=0; i<8; i++) { - double clockscale = (double)chip->clock / 2119040.0; - chip->ar_tbl[i] = ((1<clock / 2119040.0; - chip->dr_tbl[i] = ( (1<dr_tbl[i+8] = (6.25*(1<voi[i].ar_rate= chip->ar_tbl[0] * chip->external_capacity[i]; - chip->voi[i].dr_rate= chip->dr_tbl[0] * chip->external_capacity[i]; - chip->voi[i].rr_rate= chip->dr_tbl[0] * chip->external_capacity[i]; /* this is constant value */ - chip->voi[i].eg_sect= -1; - chip->voi[i].eg = 0.0; - chip->voi[i].eg_arm = 0; - chip->voi[i].pitch = -1.0; + m_voi[i].ar_rate= m_ar_tbl[0] * m_external_capacity[i]; + m_voi[i].dr_rate= m_dr_tbl[0] * m_external_capacity[i]; + m_voi[i].rr_rate= m_dr_tbl[0] * m_external_capacity[i]; /* this is constant value */ + m_voi[i].eg_sect= -1; + m_voi[i].eg = 0.0; + m_voi[i].eg_arm = 0; + m_voi[i].pitch = -1.0; } -static void msm5232_gate_update(msm5232_state *chip) +void msm5232_device::gate_update() { - int new_state = (chip->control2 & 0x20) ? chip->voi[7].GF : 0; + int new_state = (m_control2 & 0x20) ? m_voi[7].GF : 0; - if (chip->gate != new_state && !chip->gate_handler.isnull()) + if (m_gate != new_state && !m_gate_handler_func.isnull()) { - chip->gate = new_state; - chip->gate_handler(new_state); + m_gate = new_state; + m_gate_handler_func(new_state); } } - -static DEVICE_RESET( msm5232 ) -{ - msm5232_state *chip = get_safe_token(device); - int i; - - for (i=0; i<8; i++) - { - msm5232_w(device,device->machine().driver_data()->generic_space(),i,0x80); - msm5232_w(device,device->machine().driver_data()->generic_space(),i,0x00); - } - chip->noise_cnt = 0; - chip->noise_rng = 1; - chip->noise_clocks = 0; - - chip->control1 = 0; - chip->EN_out16[0] = 0; - chip->EN_out8[0] = 0; - chip->EN_out4[0] = 0; - chip->EN_out2[0] = 0; - - chip->control2 = 0; - chip->EN_out16[1] = 0; - chip->EN_out8[1] = 0; - chip->EN_out4[1] = 0; - chip->EN_out2[1] = 0; - - msm5232_gate_update(chip); -} - -static void msm5232_init(msm5232_state *chip, const msm5232_interface *intf, int clock, int rate) +void msm5232_device::init(int clock, int rate) { int j; - chip->clock = clock; - chip->rate = rate ? rate : 44100; /* avoid division by 0 */ + m_chip_clock = clock; + m_rate = rate ? rate : 44100; /* avoid division by 0 */ for (j=0; j<8; j++) { - chip->external_capacity[j] = intf->capacity[j]; + m_external_capacity[j] = m_capacity[j]; } - chip->gate_handler.resolve(intf->gate_handler_cb, *chip->device); + m_gate_handler_func.resolve(m_gate_handler_cb, *this); - msm5232_init_tables( chip ); + init_tables(); for (j=0; j<8; j++) { - memset(&chip->voi[j],0,sizeof(VOICE)); - msm5232_init_voice(chip,j); + memset(&m_voi[j],0,sizeof(VOICE)); + init_voice(j); } } -static DEVICE_STOP( msm5232 ) -{ -#ifdef SAVE_SAMPLE - fclose(sample[8]); -#endif -#ifdef SAVE_SEPARATE_CHANNELS - fclose(sample[0]); - fclose(sample[1]); - fclose(sample[2]); - fclose(sample[3]); - fclose(sample[4]); - fclose(sample[5]); - fclose(sample[6]); - fclose(sample[7]); -#endif -} -WRITE8_DEVICE_HANDLER( msm5232_w ) +WRITE8_MEMBER( msm5232_device::write ) { - msm5232_state *chip = get_safe_token(device); - if (offset > 0x0d) return; - chip->stream->update (); + m_stream->update (); if (offset < 0x08) /* pitch */ { int ch = offset&7; - chip->voi[ch].GF = ((data&0x80)>>7); + m_voi[ch].GF = ((data&0x80)>>7); if (ch == 7) - msm5232_gate_update(chip); + gate_update(); if(data&0x80) { if(data >= 0xd8) { /*if ((data&0x7f) != 0x5f) logerror("MSM5232: WRONG PITCH CODE = %2x\n",data&0x7f);*/ - chip->voi[ch].mode = 1; /* noise mode */ - chip->voi[ch].eg_sect = 0; /* Key On */ + m_voi[ch].mode = 1; /* noise mode */ + m_voi[ch].eg_sect = 0; /* Key On */ } else { - if ( chip->voi[ch].pitch != (data&0x7f) ) + if ( m_voi[ch].pitch != (data&0x7f) ) { int n; UINT16 pg; - chip->voi[ch].pitch = data&0x7f; + m_voi[ch].pitch = data&0x7f; pg = MSM5232_ROM[ data&0x7f ]; - chip->voi[ch].TG_count_period = (pg & 0x1ff) * chip->UpdateStep / 2; + m_voi[ch].TG_count_period = (pg & 0x1ff) * m_UpdateStep / 2; n = (pg>>9) & 7; /* n = bit number for 16' output */ - chip->voi[ch].TG_out16 = 1<0)? n-1: 0; - chip->voi[ch].TG_out8 = 1<0)? n-1: 0; - chip->voi[ch].TG_out4 = 1<0)? n-1: 0; - chip->voi[ch].TG_out2 = 1<voi[ch].mode = 0; /* tone mode */ - chip->voi[ch].eg_sect = 0; /* Key On */ + m_voi[ch].mode = 0; /* tone mode */ + m_voi[ch].eg_sect = 0; /* Key On */ } } else { - if ( !chip->voi[ch].eg_arm ) /* arm = 0 */ - chip->voi[ch].eg_sect = 2; /* Key Off -> go to release */ + if ( !m_voi[ch].eg_arm ) /* arm = 0 */ + m_voi[ch].eg_sect = 2; /* Key Off -> go to release */ else /* arm = 1 */ - chip->voi[ch].eg_sect = 1; /* Key Off -> go to decay */ + m_voi[ch].eg_sect = 1; /* Key Off -> go to decay */ } } else @@ -408,62 +421,62 @@ WRITE8_DEVICE_HANDLER( msm5232_w ) { case 0x08: /* group1 attack */ for (i=0; i<4; i++) - chip->voi[i].ar_rate = chip->ar_tbl[data&0x7] * chip->external_capacity[i]; + m_voi[i].ar_rate = m_ar_tbl[data&0x7] * m_external_capacity[i]; break; case 0x09: /* group2 attack */ for (i=0; i<4; i++) - chip->voi[i+4].ar_rate = chip->ar_tbl[data&0x7] * chip->external_capacity[i+4]; + m_voi[i+4].ar_rate = m_ar_tbl[data&0x7] * m_external_capacity[i+4]; break; case 0x0a: /* group1 decay */ for (i=0; i<4; i++) - chip->voi[i].dr_rate = chip->dr_tbl[data&0xf] * chip->external_capacity[i]; + m_voi[i].dr_rate = m_dr_tbl[data&0xf] * m_external_capacity[i]; break; case 0x0b: /* group2 decay */ for (i=0; i<4; i++) - chip->voi[i+4].dr_rate = chip->dr_tbl[data&0xf] * chip->external_capacity[i+4]; + m_voi[i+4].dr_rate = m_dr_tbl[data&0xf] * m_external_capacity[i+4]; break; case 0x0c: /* group1 control */ - /*if (chip->control1 != data) + /*if (m_control1 != data) logerror("msm5232: control1 ctrl=%x OE=%x\n", data&0xf0, data&0x0f);*/ /*if (data & 0x10) popmessage("msm5232: control1 ctrl=%2x\n", data);*/ - chip->control1 = data; + m_control1 = data; for (i=0; i<4; i++) - chip->voi[i].eg_arm = data&0x10; + m_voi[i].eg_arm = data&0x10; - chip->EN_out16[0] = (data&1) ? ~0:0; - chip->EN_out8[0] = (data&2) ? ~0:0; - chip->EN_out4[0] = (data&4) ? ~0:0; - chip->EN_out2[0] = (data&8) ? ~0:0; + m_EN_out16[0] = (data&1) ? ~0:0; + m_EN_out8[0] = (data&2) ? ~0:0; + m_EN_out4[0] = (data&4) ? ~0:0; + m_EN_out2[0] = (data&8) ? ~0:0; break; case 0x0d: /* group2 control */ - /*if (chip->control2 != data) + /*if (m_control2 != data) logerror("msm5232: control2 ctrl=%x OE=%x\n", data&0xf0, data&0x0f);*/ /*if (data & 0x10) popmessage("msm5232: control2 ctrl=%2x\n", data);*/ - chip->control2 = data; - msm5232_gate_update(chip); + m_control2 = data; + gate_update(); for (i=0; i<4; i++) - chip->voi[i+4].eg_arm = data&0x10; + m_voi[i+4].eg_arm = data&0x10; - chip->EN_out16[1] = (data&1) ? ~0:0; - chip->EN_out8[1] = (data&2) ? ~0:0; - chip->EN_out4[1] = (data&4) ? ~0:0; - chip->EN_out2[1] = (data&8) ? ~0:0; + m_EN_out16[1] = (data&1) ? ~0:0; + m_EN_out8[1] = (data&2) ? ~0:0; + m_EN_out4[1] = (data&4) ? ~0:0; + m_EN_out2[1] = (data&8) ? ~0:0; break; } @@ -476,10 +489,10 @@ WRITE8_DEVICE_HANDLER( msm5232_w ) #define VMAX 32768 -INLINE void EG_voices_advance(msm5232_state *chip) +void msm5232_device::EG_voices_advance() { - VOICE *voi = &chip->voi[0]; - int samplerate = chip->rate; + VOICE *voi = &m_voi[0]; + int samplerate = m_rate; int i; i = 8; @@ -578,9 +591,9 @@ INLINE void EG_voices_advance(msm5232_state *chip) static int o2,o4,o8,o16,solo8,solo16; -INLINE void TG_group_advance(msm5232_state *chip, int groupidx) +void msm5232_device::TG_group_advance(int groupidx) { - VOICE *voi = &chip->voi[groupidx*4]; + VOICE *voi = &m_voi[groupidx*4]; int i; o2 = o4 = o8 = o16 = solo8 = solo16 = 0; @@ -636,10 +649,10 @@ INLINE void TG_group_advance(msm5232_state *chip, int groupidx) } else /* generate noise */ { - if (chip->noise_clocks&8) out16+=(1<noise_clocks&4) out8 +=(1<noise_clocks&2) out4 +=(1<noise_clocks&1) out2 +=(1<0); /* cut off disabled output lines */ - o16 &= chip->EN_out16[groupidx]; - o8 &= chip->EN_out8 [groupidx]; - o4 &= chip->EN_out4 [groupidx]; - o2 &= chip->EN_out2 [groupidx]; + o16 &= m_EN_out16[groupidx]; + o8 &= m_EN_out8 [groupidx]; + o4 &= m_EN_out4 [groupidx]; + o2 &= m_EN_out2 [groupidx]; } @@ -705,9 +718,31 @@ INLINE void TG_group_advance(msm5232_state *chip, int groupidx) #endif -static STREAM_UPDATE( MSM5232_update_one ) +/* MAME Interface */ +void msm5232_device::postload() +{ + init_tables(); +} + +void msm5232_device::set_clock(int clock) +{ + if (m_chip_clock != clock) + { + m_stream->update (); + m_chip_clock = clock; + m_rate = clock/CLOCK_RATE_DIVIDER; + init_tables(); + m_stream->set_sample_rate(m_rate); + } +} + + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void msm5232_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - msm5232_state * chip = (msm5232_state *)param; stream_sample_t *buf1 = outputs[0]; stream_sample_t *buf2 = outputs[1]; stream_sample_t *buf3 = outputs[2]; @@ -724,9 +759,9 @@ static STREAM_UPDATE( MSM5232_update_one ) for (i=0; inoise_cnt+=chip->noise_step) >> STEP_SH; - chip->noise_cnt &= ((1<> STEP_SH; + m_noise_cnt &= ((1< 0) { - int tmp = chip->noise_rng & (1<<16); /* store current level */ + int tmp = m_noise_rng & (1<<16); /* store current level */ - if (chip->noise_rng&1) - chip->noise_rng ^= 0x24000; - chip->noise_rng>>=1; + if (m_noise_rng&1) + m_noise_rng ^= 0x24000; + m_noise_rng>>=1; - if ( (chip->noise_rng & (1<<16)) != tmp ) /* level change detect */ - chip->noise_clocks++; + if ( (m_noise_rng & (1<<16)) != tmp ) /* level change detect */ + m_noise_clocks++; cnt--; } } - bufnoise[i] = (chip->noise_rng & (1<<16)) ? 32767 : 0; + bufnoise[i] = (m_noise_rng & (1<<16)) ? 32767 : 0; } } - - - -/* MAME Interface */ -static void msm5232_postload(msm5232_state *chip) -{ - msm5232_init_tables(chip); -} - -static DEVICE_START( msm5232 ) -{ - const msm5232_interface *intf = (const msm5232_interface *)device->static_config(); - int rate = device->clock()/CLOCK_RATE_DIVIDER; - msm5232_state *chip = get_safe_token(device); - int voicenum; - - chip->device = device; - - msm5232_init(chip, intf, device->clock(), rate); - - chip->stream = device->machine().sound().stream_alloc(*device, 0, 11, rate, chip, MSM5232_update_one); - - /* register with the save state system */ - device->machine().save().register_postload(save_prepost_delegate(FUNC(msm5232_postload), chip)); - device->save_item(NAME(chip->EN_out16)); - device->save_item(NAME(chip->EN_out8)); - device->save_item(NAME(chip->EN_out4)); - device->save_item(NAME(chip->EN_out2)); - device->save_item(NAME(chip->noise_cnt)); - device->save_item(NAME(chip->noise_rng)); - device->save_item(NAME(chip->noise_clocks)); - device->save_item(NAME(chip->control1)); - device->save_item(NAME(chip->control2)); - device->save_item(NAME(chip->gate)); - device->save_item(NAME(chip->clock)); - device->save_item(NAME(chip->rate)); - - /* register voice-specific data for save states */ - for (voicenum = 0; voicenum < 8; voicenum++) - { - VOICE *voice = &chip->voi[voicenum]; - - device->save_item(NAME(voice->mode), voicenum); - device->save_item(NAME(voice->TG_count_period), voicenum); - device->save_item(NAME(voice->TG_cnt), voicenum); - device->save_item(NAME(voice->TG_out16), voicenum); - device->save_item(NAME(voice->TG_out8), voicenum); - device->save_item(NAME(voice->TG_out4), voicenum); - device->save_item(NAME(voice->TG_out2), voicenum); - device->save_item(NAME(voice->egvol), voicenum); - device->save_item(NAME(voice->eg_sect), voicenum); - device->save_item(NAME(voice->counter), voicenum); - device->save_item(NAME(voice->eg), voicenum); - device->save_item(NAME(voice->eg_arm), voicenum); - device->save_item(NAME(voice->ar_rate), voicenum); - device->save_item(NAME(voice->dr_rate), voicenum); - device->save_item(NAME(voice->pitch), voicenum); - device->save_item(NAME(voice->GF), voicenum); - } -} - -void msm5232_set_clock(device_t *device, int clock) -{ - msm5232_state *chip = get_safe_token(device); - - if (chip->clock != clock) - { - chip->stream->update (); - chip->clock = clock; - chip->rate = clock/CLOCK_RATE_DIVIDER; - msm5232_init_tables( chip ); - chip->stream->set_sample_rate(chip->rate); - } -} - -const device_type MSM5232 = &device_creator; - -msm5232_device::msm5232_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, MSM5232, "MSM5232", tag, owner, clock, "msm5232", __FILE__), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(msm5232_state); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void msm5232_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void msm5232_device::device_start() -{ - DEVICE_START_NAME( msm5232 )(this); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void msm5232_device::device_reset() -{ - DEVICE_RESET_NAME( msm5232 )(this); -} - -//------------------------------------------------- -// device_stop - device-specific stop -//------------------------------------------------- - -void msm5232_device::device_stop() -{ - DEVICE_STOP_NAME( msm5232 )(this); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void msm5232_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) -{ - // should never get here - fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); -} diff --git a/src/emu/sound/msm5232.h b/src/emu/sound/msm5232.h index ff9dbb2bf9d..6f52e81df34 100644 --- a/src/emu/sound/msm5232.h +++ b/src/emu/sound/msm5232.h @@ -3,27 +3,54 @@ #ifndef __MSM5232_H__ #define __MSM5232_H__ -#include "devlegcy.h" + +struct VOICE { + UINT8 mode; + + int TG_count_period; + int TG_count; + + UINT8 TG_cnt; /* 7 bits binary counter (frequency output) */ + UINT8 TG_out16; /* bit number (of TG_cnt) for 16' output */ + UINT8 TG_out8; /* bit number (of TG_cnt) for 8' output */ + UINT8 TG_out4; /* bit number (of TG_cnt) for 4' output */ + UINT8 TG_out2; /* bit number (of TG_cnt) for 2' output */ + + int egvol; + int eg_sect; + int counter; + int eg; + + UINT8 eg_arm; /* attack/release mode */ + + double ar_rate; + double dr_rate; + double rr_rate; + + int pitch; /* current pitch data */ + + int GF; +}; + struct msm5232_interface { - double capacity[8]; /* in Farads, capacitors connected to pins: 24,25,26,27 and 37,38,39,40 */ - devcb_write_line gate_handler_cb; /* callback called when the GATE output pin changes state */ + double m_capacity[8]; /* in Farads, capacitors connected to pins: 24,25,26,27 and 37,38,39,40 */ + devcb_write_line m_gate_handler_cb; /* callback called when the GATE output pin changes state */ }; -DECLARE_WRITE8_DEVICE_HANDLER( msm5232_w ); - -void msm5232_set_clock(device_t *device, int clock); class msm5232_device : public device_t, - public device_sound_interface + public device_sound_interface, + public msm5232_interface { public: msm5232_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~msm5232_device() { global_free(m_token); } + ~msm5232_device() {} + + DECLARE_WRITE8_MEMBER( write ); + void set_clock(int clock); - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } protected: // device-level overrides virtual void device_config_complete(); @@ -33,9 +60,47 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); -private: + + private: // internal state - void *m_token; + sound_stream *m_stream; + + VOICE m_voi[8]; + + UINT32 m_EN_out16[2]; /* enable 16' output masks for both groups (0-disabled ; ~0 -enabled) */ + UINT32 m_EN_out8[2]; /* enable 8' output masks */ + UINT32 m_EN_out4[2]; /* enable 4' output masks */ + UINT32 m_EN_out2[2]; /* enable 2' output masks */ + + int m_noise_cnt; + int m_noise_step; + int m_noise_rng; + int m_noise_clocks; /* number of the noise_rng (output) level changes */ + + unsigned int m_UpdateStep; + + /* rate tables */ + double m_ar_tbl[8]; + double m_dr_tbl[16]; + + UINT8 m_control1; + UINT8 m_control2; + + int m_gate; /* current state of the GATE output */ + + int m_chip_clock; /* chip clock in Hz */ + int m_rate; /* sample rate in Hz */ + + double m_external_capacity[8]; /* in Farads, eg 0.39e-6 = 0.36 uF (microFarads) */ + devcb_resolved_write_line m_gate_handler_func;/* callback called when the GATE output pin changes state */ + + void init_tables(); + void init_voice(int i); + void gate_update(); + void init(int clock, int rate); + void EG_voices_advance(); + void TG_group_advance(int groupidx); + void postload(); }; extern const device_type MSM5232; diff --git a/src/mame/drivers/40love.c b/src/mame/drivers/40love.c index e53b4e9e7cd..2de9d4838d5 100644 --- a/src/mame/drivers/40love.c +++ b/src/mame/drivers/40love.c @@ -227,7 +227,6 @@ Notes - Has jumper setting for 122HZ or 61HZ) #include "cpu/m6805/m6805.h" #include "sound/ay8910.h" #include "sound/dac.h" -#include "sound/msm5232.h" #include "machine/buggychl.h" #include "includes/40love.h" @@ -739,7 +738,7 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, fortyl_state ) AM_RANGE(0x0000, 0xbfff) AM_ROM AM_RANGE(0xc000, 0xc7ff) AM_RAM AM_RANGE(0xc800, 0xc801) AM_DEVWRITE("aysnd", ay8910_device, address_data_w) - AM_RANGE(0xca00, 0xca0d) AM_DEVWRITE_LEGACY("msm", msm5232_w) + AM_RANGE(0xca00, 0xca0d) AM_DEVWRITE("msm", msm5232_device, write) AM_RANGE(0xcc00, 0xcc00) AM_WRITE(sound_control_0_w) AM_RANGE(0xce00, 0xce00) AM_WRITE(sound_control_1_w) AM_RANGE(0xd800, 0xd800) AM_READ(soundlatch_byte_r) AM_WRITE(to_main_w) diff --git a/src/mame/drivers/bigevglf.c b/src/mame/drivers/bigevglf.c index c4ac82538cc..687f5e5d805 100644 --- a/src/mame/drivers/bigevglf.c +++ b/src/mame/drivers/bigevglf.c @@ -58,7 +58,6 @@ J1100072A #include "emu.h" #include "cpu/z80/z80.h" #include "sound/ay8910.h" -#include "sound/msm5232.h" #include "cpu/m6805/m6805.h" #include "includes/bigevglf.h" @@ -364,7 +363,7 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, bigevglf_state ) AM_RANGE(0x0000, 0xbfff) AM_ROM AM_RANGE(0xc000, 0xc7ff) AM_RAM AM_RANGE(0xc800, 0xc801) AM_DEVWRITE("aysnd", ay8910_device, address_data_w) - AM_RANGE(0xca00, 0xca0d) AM_DEVWRITE_LEGACY("msm", msm5232_w) + AM_RANGE(0xca00, 0xca0d) AM_DEVWRITE("msm", msm5232_device, write) AM_RANGE(0xcc00, 0xcc00) AM_WRITENOP AM_RANGE(0xce00, 0xce00) AM_WRITENOP AM_RANGE(0xd800, 0xd800) AM_READWRITE(sound_command_r, beg_fromsound_w) /* write to D800 sets bit 1 in status */ diff --git a/src/mame/drivers/buggychl.c b/src/mame/drivers/buggychl.c index ad430a18b73..6f13cfc907b 100644 --- a/src/mame/drivers/buggychl.c +++ b/src/mame/drivers/buggychl.c @@ -79,7 +79,6 @@ Dip locations and factory settings verified from dip listing #include "cpu/z80/z80.h" #include "cpu/m6805/m6805.h" #include "sound/ay8910.h" -#include "sound/msm5232.h" #include "machine/buggychl.h" #include "includes/buggychl.h" @@ -164,7 +163,7 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, buggychl_state ) AM_RANGE(0x4000, 0x47ff) AM_RAM AM_RANGE(0x4800, 0x4801) AM_DEVWRITE("ay1", ay8910_device, address_data_w) AM_RANGE(0x4802, 0x4803) AM_DEVWRITE("ay2", ay8910_device, address_data_w) - AM_RANGE(0x4810, 0x481d) AM_DEVWRITE_LEGACY("msm", msm5232_w) + AM_RANGE(0x4810, 0x481d) AM_DEVWRITE("msm", msm5232_device, write) AM_RANGE(0x4820, 0x4820) AM_RAM /* VOL/BAL for the 7630 on the MSM5232 output */ AM_RANGE(0x4830, 0x4830) AM_RAM /* TRBL/BASS for the 7630 on the MSM5232 output */ AM_RANGE(0x5000, 0x5000) AM_READ(soundlatch_byte_r) diff --git a/src/mame/drivers/equites.c b/src/mame/drivers/equites.c index f346179ba91..2c1f98a30c4 100644 --- a/src/mame/drivers/equites.c +++ b/src/mame/drivers/equites.c @@ -368,7 +368,6 @@ D #include "cpu/alph8201/alph8201.h" #include "cpu/i8085/i8085.h" #include "sound/ay8910.h" -#include "sound/msm5232.h" #include "sound/dac.h" #include "sound/samples.h" #include "machine/nvram.h" @@ -404,7 +403,7 @@ TIMER_CALLBACK_MEMBER(equites_state::equites_frq_adjuster_callback) { UINT8 frq = ioport(FRQ_ADJUSTER_TAG)->read(); - msm5232_set_clock(m_msm, MSM5232_MIN_CLOCK + frq * (MSM5232_MAX_CLOCK - MSM5232_MIN_CLOCK) / 100); + m_msm->set_clock(MSM5232_MIN_CLOCK + frq * (MSM5232_MAX_CLOCK - MSM5232_MIN_CLOCK) / 100); //popmessage("8155: C %02x A %02x AY: A %02x B %02x Unk:%x", m_eq8155_port_c, m_eq8155_port_a, m_ay_port_a, m_ay_port_b, m_eq_cymbal_ctrl & 15); m_cymvol *= 0.94f; @@ -740,7 +739,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, equites_state ) AM_RANGE(0x0000, 0xbfff) AM_ROM AM_RANGE(0xc000, 0xc000) AM_READ(soundlatch_byte_r) - AM_RANGE(0xc080, 0xc08d) AM_DEVWRITE_LEGACY("msm", msm5232_w) + AM_RANGE(0xc080, 0xc08d) AM_DEVWRITE("msm", msm5232_device, write) AM_RANGE(0xc0a0, 0xc0a1) AM_DEVWRITE("aysnd", ay8910_device, data_address_w) AM_RANGE(0xc0b0, 0xc0b0) AM_WRITENOP // n.c. AM_RANGE(0xc0c0, 0xc0c0) AM_WRITE(equites_cymbal_ctrl_w) diff --git a/src/mame/drivers/flstory.c b/src/mame/drivers/flstory.c index 9cf887c2c7e..5e5a2db8a12 100644 --- a/src/mame/drivers/flstory.c +++ b/src/mame/drivers/flstory.c @@ -13,7 +13,6 @@ #include "cpu/z80/z80.h" #include "cpu/m6805/m6805.h" #include "sound/ay8910.h" -#include "sound/msm5232.h" #include "sound/dac.h" #include "includes/flstory.h" @@ -429,7 +428,7 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, flstory_state ) AM_RANGE(0x0000, 0xbfff) AM_ROM AM_RANGE(0xc000, 0xc7ff) AM_RAM AM_RANGE(0xc800, 0xc801) AM_DEVWRITE("aysnd", ay8910_device, address_data_w) - AM_RANGE(0xca00, 0xca0d) AM_DEVWRITE_LEGACY("msm", msm5232_w) + AM_RANGE(0xca00, 0xca0d) AM_DEVWRITE("msm", msm5232_device, write) AM_RANGE(0xcc00, 0xcc00) AM_WRITE(sound_control_0_w) AM_RANGE(0xce00, 0xce00) AM_WRITE(sound_control_1_w) AM_RANGE(0xd800, 0xd800) AM_READ(soundlatch_byte_r) AM_WRITE(to_main_w) diff --git a/src/mame/drivers/ladyfrog.c b/src/mame/drivers/ladyfrog.c index 2a621b9356f..29b6ca8b91e 100644 --- a/src/mame/drivers/ladyfrog.c +++ b/src/mame/drivers/ladyfrog.c @@ -49,7 +49,6 @@ Notes: #include "emu.h" #include "cpu/z80/z80.h" #include "sound/ay8910.h" -#include "sound/msm5232.h" #include "includes/ladyfrog.h" @@ -150,7 +149,7 @@ static ADDRESS_MAP_START( ladyfrog_sound_map, AS_PROGRAM, 8, ladyfrog_state ) AM_RANGE(0xc000, 0xc7ff) AM_RAM AM_RANGE(0xc800, 0xc801) AM_WRITENOP AM_RANGE(0xc802, 0xc803) AM_DEVWRITE("aysnd", ay8910_device, address_data_w) - AM_RANGE(0xc900, 0xc90d) AM_DEVWRITE_LEGACY("msm", msm5232_w) + AM_RANGE(0xc900, 0xc90d) AM_DEVWRITE("msm", msm5232_device, write) AM_RANGE(0xca00, 0xca00) AM_WRITENOP AM_RANGE(0xcb00, 0xcb00) AM_WRITENOP AM_RANGE(0xcc00, 0xcc00) AM_WRITENOP diff --git a/src/mame/drivers/msisaac.c b/src/mame/drivers/msisaac.c index 101cfac1bba..45e94f2ce80 100644 --- a/src/mame/drivers/msisaac.c +++ b/src/mame/drivers/msisaac.c @@ -10,7 +10,6 @@ #include "cpu/z80/z80.h" #include "cpu/m6805/m6805.h" #include "sound/ay8910.h" -#include "sound/msm5232.h" #include "machine/buggychl.h" #include "includes/msisaac.h" @@ -259,7 +258,7 @@ static ADDRESS_MAP_START( msisaac_sound_map, AS_PROGRAM, 8, msisaac_state ) AM_RANGE(0x4000, 0x47ff) AM_RAM AM_RANGE(0x8000, 0x8001) AM_DEVWRITE("ay1", ay8910_device, address_data_w) AM_RANGE(0x8002, 0x8003) AM_DEVWRITE("ay2", ay8910_device, address_data_w) - AM_RANGE(0x8010, 0x801d) AM_DEVWRITE_LEGACY("msm", msm5232_w) + AM_RANGE(0x8010, 0x801d) AM_DEVWRITE("msm", msm5232_device, write) AM_RANGE(0x8020, 0x8020) AM_WRITE(sound_control_0_w) AM_RANGE(0x8030, 0x8030) AM_WRITE(sound_control_1_w) AM_RANGE(0xc000, 0xc000) AM_READ(soundlatch_byte_r) diff --git a/src/mame/drivers/nycaptor.c b/src/mame/drivers/nycaptor.c index 025a2514c58..a0a4aa939dd 100644 --- a/src/mame/drivers/nycaptor.c +++ b/src/mame/drivers/nycaptor.c @@ -196,7 +196,6 @@ Stephh's additional notes (based on the game Z80 code and some tests) : #include "cpu/m6805/m6805.h" #include "includes/taitoipt.h" #include "sound/ay8910.h" -#include "sound/msm5232.h" #include "includes/nycaptor.h" @@ -382,7 +381,7 @@ static ADDRESS_MAP_START( nycaptor_sound_map, AS_PROGRAM, 8, nycaptor_state ) AM_RANGE(0xc000, 0xc7ff) AM_RAM AM_RANGE(0xc800, 0xc801) AM_DEVWRITE("ay1", ay8910_device, address_data_w) AM_RANGE(0xc802, 0xc803) AM_DEVWRITE("ay2", ay8910_device, address_data_w) - AM_RANGE(0xc900, 0xc90d) AM_DEVWRITE_LEGACY("msm", msm5232_w) + AM_RANGE(0xc900, 0xc90d) AM_DEVWRITE("msm", msm5232_device, write) AM_RANGE(0xca00, 0xca00) AM_WRITENOP AM_RANGE(0xcb00, 0xcb00) AM_WRITENOP AM_RANGE(0xcc00, 0xcc00) AM_WRITENOP diff --git a/src/mame/includes/40love.h b/src/mame/includes/40love.h index f2dec62e1f2..b5a316b6d82 100644 --- a/src/mame/includes/40love.h +++ b/src/mame/includes/40love.h @@ -109,5 +109,5 @@ public: void draw_pixram( bitmap_ind16 &bitmap, const rectangle &cliprect ); required_device m_maincpu; optional_device m_mcu; - optional_device m_msm; + required_device m_msm; }; diff --git a/src/mame/includes/bigevglf.h b/src/mame/includes/bigevglf.h index 634012b7dcf..47e0aa76cce 100644 --- a/src/mame/includes/bigevglf.h +++ b/src/mame/includes/bigevglf.h @@ -1,3 +1,4 @@ +#include "sound/msm5232.h" class bigevglf_state : public driver_device { @@ -9,7 +10,8 @@ public: m_spriteram2(*this, "spriteram2"), m_audiocpu(*this, "audiocpu"), m_mcu(*this, "mcu"), - m_maincpu(*this, "maincpu") { } + m_maincpu(*this, "maincpu"), + m_msm(*this, "msm") { } /* memory pointers */ required_shared_ptr m_paletteram; @@ -98,4 +100,5 @@ public: TIMER_CALLBACK_MEMBER(deferred_ls74_w); void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); required_device m_maincpu; + required_device m_msm; }; diff --git a/src/mame/includes/buggychl.h b/src/mame/includes/buggychl.h index 166e621b867..0ce1314efbe 100644 --- a/src/mame/includes/buggychl.h +++ b/src/mame/includes/buggychl.h @@ -2,6 +2,8 @@ buggychl */ +#include "sound/msm5232.h" + class buggychl_state : public driver_device { public: @@ -14,7 +16,8 @@ public: m_scrollh(*this, "scrollh"), m_audiocpu(*this, "audiocpu"), m_maincpu(*this, "maincpu"), - m_mcu(*this, "mcu") { } + m_mcu(*this, "mcu"), + m_msm(*this, "msm") { } /* memory pointers */ required_shared_ptr m_charram; @@ -66,4 +69,5 @@ public: void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); required_device m_maincpu; required_device m_mcu; + required_device m_msm; }; diff --git a/src/mame/includes/ladyfrog.h b/src/mame/includes/ladyfrog.h index 518a157f22a..63da9bd48e6 100644 --- a/src/mame/includes/ladyfrog.h +++ b/src/mame/includes/ladyfrog.h @@ -4,6 +4,8 @@ *************************************************************************/ +#include "sound/msm5232.h" + class ladyfrog_state : public driver_device { public: @@ -12,7 +14,8 @@ public: m_videoram(*this, "videoram"), m_scrlram(*this, "scrlram"), m_audiocpu(*this, "audiocpu"), - m_maincpu(*this, "maincpu") { } + m_maincpu(*this, "maincpu"), + m_msm(*this, "msm") { } /* memory pointers */ required_shared_ptr m_videoram; @@ -64,4 +67,5 @@ public: TIMER_CALLBACK_MEMBER(nmi_callback); void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); required_device m_maincpu; + required_device m_msm; }; diff --git a/src/mame/includes/nycaptor.h b/src/mame/includes/nycaptor.h index 7bd21ef1080..9353b6172e7 100644 --- a/src/mame/includes/nycaptor.h +++ b/src/mame/includes/nycaptor.h @@ -1,3 +1,4 @@ +#include "sound/msm5232.h" class nycaptor_state : public driver_device { @@ -10,7 +11,8 @@ public: m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), m_subcpu(*this, "sub"), - m_mcu(*this, "mcu"){ } + m_mcu(*this, "mcu"), + m_msm(*this, "msm") { } /* memory pointers */ required_shared_ptr m_videoram; @@ -54,6 +56,7 @@ public: required_device m_audiocpu; required_device m_subcpu; optional_device m_mcu; + required_device m_msm; DECLARE_WRITE8_MEMBER(sub_cpu_halt_w); DECLARE_READ8_MEMBER(from_snd_r); DECLARE_WRITE8_MEMBER(to_main_w);