diff options
author | Scott Stone <tafoid@users.noreply.github.com> | 2013-07-23 02:15:20 +0000 |
---|---|---|
committer | Scott Stone <tafoid@users.noreply.github.com> | 2013-07-23 02:15:20 +0000 |
commit | 68a838669dbfab35526b75ac285aac1d52b3b134 (patch) | |
tree | fae8d15a5dca464cd52a85d30489956a0bd52b67 | |
parent | 8e4b11a87eb0fd04945a36955c6fb005eb639125 (diff) |
Modernized TX1 custom sound device. [Osso]
-rw-r--r-- | src/mame/audio/tx1.c | 596 | ||||
-rw-r--r-- | src/mame/drivers/tx1.c | 20 | ||||
-rw-r--r-- | src/mame/includes/tx1.h | 77 |
3 files changed, 322 insertions, 371 deletions
diff --git a/src/mame/audio/tx1.c b/src/mame/audio/tx1.c index 6200cb785a3..7191e3d23c0 100644 --- a/src/mame/audio/tx1.c +++ b/src/mame/audio/tx1.c @@ -8,89 +8,135 @@ #include "sound/ay8910.h" #include "video/resnet.h" #include "includes/tx1.h" -#include "devlegcy.h" - /************************************* * - * 8253 Programmable Interval Timer + * TX-1 * *************************************/ -struct pit8253_state + +/* RC oscillator: 1785Hz */ +#define TX1_NOISE_CLOCK (1/(1000.0e-12 * 560000.0)) +#define TX1_PIT_CLOCK (TX1_PIXEL_CLOCK / 16) +#define TX1_FRAC 30 + +#define TX1_SHUNT (250.0) +#define TX1_R0 (180000.0 + TX1_SHUNT) +#define TX1_R1 (56000.0 + TX1_SHUNT) +#define TX1_R2 (22000.0 + TX1_SHUNT) +#define TX1_R (100000.0 + TX1_SHUNT) +#define TX1_RI (180000.0) + +static const double tx1_engine_gains[16] = { - union - { -#ifdef LSB_FIRST - struct { UINT8 LSB; UINT8 MSB; }; -#else - struct { UINT8 MSB; UINT8 LSB; }; -#endif - UINT16 val; - } counts[3]; - - int idx[3]; + -( TX1_R )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_R0) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_R1) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_R1 + 1.0/TX1_R0) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_R2) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_R2 + 1.0/TX1_R0) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_R2 + 1.0/TX1_R1) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_R2 + 1.0/TX1_R1 + 1.0/TX1_R0) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT ) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R0) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R1) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R1 + 1.0/TX1_R0) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R2) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R2 + 1.0/TX1_R0) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R2 + 1.0/TX1_R1) )/TX1_RI, + -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R2 + 1.0/TX1_R1 + 1.0/TX1_R0) )/TX1_RI }; -struct tx1_sound_state + +const device_type TX1 = &device_creator<tx1_sound_device>; + +tx1_sound_device::tx1_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, TX1, "TX-1 Custom", tag, owner, clock, "tx1_sound", __FILE__), + device_sound_interface(mconfig, *this) { - sound_stream *m_stream; - UINT32 m_freq_to_step; - UINT32 m_step0; - UINT32 m_step1; - UINT32 m_step2; - - pit8253_state m_pit8253; - - UINT8 m_ay_outputa; - UINT8 m_ay_outputb; - - stream_sample_t m_pit0; - stream_sample_t m_pit1; - stream_sample_t m_pit2; - - double m_weights0[4]; - double m_weights1[3]; - double m_weights2[3]; - int m_eng0[4]; - int m_eng1[4]; - int m_eng2[4]; - - int m_noise_lfsra; - int m_noise_lfsrb; - int m_noise_lfsrc; - int m_noise_lfsrd; - int m_noise_counter; - UINT8 m_ym1_outputa; - UINT8 m_ym2_outputa; - UINT8 m_ym2_outputb; - UINT16 m_eng_voltages[16]; -}; +} + +tx1_sound_device::tx1_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) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_sound_interface(mconfig, *this), + m_stream(NULL), + m_freq_to_step(0), + m_step0(0), + m_step1(0), + m_step2(0), + m_ay_outputa(0), + m_ay_outputb(0), + m_pit0(0), + m_pit1(0), + m_pit2(0), + m_noise_lfsra(0), + m_noise_lfsrb(1), + m_noise_lfsrc(0), + m_noise_lfsrd(0), + m_noise_counter(0), + m_ym1_outputa(0), + m_ym2_outputa(0), + m_ym2_outputb(0) +{ +} +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void tx1_sound_device::device_config_complete() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- -INLINE tx1_sound_state *get_safe_token(device_t *device) +void tx1_sound_device::device_start() { - assert(device != NULL); - assert(device->type() == TX1 || device->type() == BUGGYBOY); + static const int r0[4] = { 390e3, 180e3, 180e3, 180e3 }; + static const int r1[3] = { 180e3, 390e3, 56e3 }; + static const int r2[3] = { 390e3, 390e3, 180e3 }; - return (tx1_sound_state *)downcast<tx1_sound_device *>(device)->token(); + + /* Allocate the stream */ + m_stream = machine().sound().stream_alloc(*this, 0, 2, machine().sample_rate(), this); + m_freq_to_step = (double)(1 << TX1_FRAC) / (double)machine().sample_rate(); + + /* Compute the engine resistor weights */ + compute_resistor_weights(0, 10000, -1.0, + 4, &r0[0], m_weights0, 0, 0, + 3, &r1[0], m_weights1, 0, 0, + 3, &r2[0], m_weights2, 0, 0); } -WRITE8_DEVICE_HANDLER( tx1_pit8253_w ) +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void tx1_sound_device::device_reset() +{ + m_step0 = m_step1 = m_step2 = 0; +} + + +WRITE8_MEMBER( tx1_sound_device::pit8253_w ) { - tx1_sound_state *state = get_safe_token(device); - state->m_stream->update(); + m_stream->update(); if (offset < 3) { - if (state->m_pit8253.idx[offset] == 0) + if (m_pit8253.idx[offset] == 0) { - state->m_pit8253.counts[offset].LSB = data; - state->m_pit8253.idx[offset] = 1; + m_pit8253.counts[offset].LSB = data; + m_pit8253.idx[offset] = 1; } else { - state->m_pit8253.counts[offset].MSB = data; - state->m_pit8253.idx[offset] = 0; + m_pit8253.counts[offset].MSB = data; + m_pit8253.idx[offset] = 0; } } else @@ -100,58 +146,20 @@ WRITE8_DEVICE_HANDLER( tx1_pit8253_w ) if (mode == 3) { int cntsel = (data >> 6) & 3; - state->m_pit8253.idx[cntsel] = 0; - state->m_pit8253.counts[cntsel].val = 0; + m_pit8253.idx[cntsel] = 0; + m_pit8253.counts[cntsel].val = 0; } else mame_printf_debug("PIT8253: Unsupported mode %d.\n", mode); } } -READ8_DEVICE_HANDLER( tx1_pit8253_r ) +READ8_MEMBER( tx1_sound_device::pit8253_r ) { mame_printf_debug("PIT R: %x", offset); return 0; } -/************************************* - * - * TX-1 - * - *************************************/ - -/* RC oscillator: 1785Hz */ -#define TX1_NOISE_CLOCK (1/(1000.0e-12 * 560000.0)) -#define TX1_PIT_CLOCK (TX1_PIXEL_CLOCK / 16) -#define TX1_FRAC 30 - -#define TX1_SHUNT (250.0) -#define TX1_R0 (180000.0 + TX1_SHUNT) -#define TX1_R1 (56000.0 + TX1_SHUNT) -#define TX1_R2 (22000.0 + TX1_SHUNT) -#define TX1_R (100000.0 + TX1_SHUNT) -#define TX1_RI (180000.0) - -static const double tx1_engine_gains[16] = -{ - -( TX1_R )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_R0) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_R1) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_R1 + 1.0/TX1_R0) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_R2) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_R2 + 1.0/TX1_R0) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_R2 + 1.0/TX1_R1) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_R2 + 1.0/TX1_R1 + 1.0/TX1_R0) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT ) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R0) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R1) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R1 + 1.0/TX1_R0) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R2) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R2 + 1.0/TX1_R0) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R2 + 1.0/TX1_R1) )/TX1_RI, - -( 1.0/(1.0/TX1_R + 1.0/TX1_SHUNT + 1.0/TX1_R2 + 1.0/TX1_R1 + 1.0/TX1_R0) )/TX1_RI -}; - /*************************************************************************** AY-8910 port mappings: @@ -170,28 +178,26 @@ static const double tx1_engine_gains[16] = ***************************************************************************/ -WRITE8_DEVICE_HANDLER( tx1_ay8910_a_w ) +WRITE8_MEMBER( tx1_sound_device::ay8910_a_w ) { - tx1_sound_state *state = get_safe_token(device); - state->m_stream->update(); + m_stream->update(); /* All outputs inverted */ - state->m_ay_outputa = ~data; + m_ay_outputa = ~data; } -WRITE8_DEVICE_HANDLER( tx1_ay8910_b_w ) +WRITE8_MEMBER( tx1_sound_device::ay8910_b_w ) { - tx1_sound_state *state = get_safe_token(device); double gain; - state->m_stream->update(); + m_stream->update(); /* Only B3-0 are inverted */ - state->m_ay_outputb = data ^ 0xf; + m_ay_outputb = data ^ 0xf; /* It'll do until we get quadrophonic speaker support! */ - gain = BIT(state->m_ay_outputb, 4) ? 1.5 : 2.0; + gain = BIT(m_ay_outputb, 4) ? 1.5 : 2.0; device_sound_interface *sound; - device->interface(sound); + interface(sound); sound->set_output_gain(0, gain); sound->set_output_gain(1, gain); sound->set_output_gain(2, gain); @@ -237,9 +243,12 @@ INLINE void update_engine(int eng[4]) } -static STREAM_UPDATE( tx1_stream_update ) +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void tx1_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - tx1_sound_state *state = get_safe_token(device); UINT32 step_0, step_1, step_2; double /*gain_0, gain_1,*/ gain_2, gain_3; @@ -251,75 +260,48 @@ static STREAM_UPDATE( tx1_stream_update ) memset(outputs[1], 0, samples * sizeof(*outputs[1])); /* 8253 outputs for the player/opponent engine sounds. */ - step_0 = state->m_pit8253.counts[0].val ? (TX1_PIT_CLOCK / state->m_pit8253.counts[0].val) * state->m_freq_to_step : 0; - step_1 = state->m_pit8253.counts[1].val ? (TX1_PIT_CLOCK / state->m_pit8253.counts[1].val) * state->m_freq_to_step : 0; - step_2 = state->m_pit8253.counts[2].val ? (TX1_PIT_CLOCK / state->m_pit8253.counts[2].val) * state->m_freq_to_step : 0; + step_0 = m_pit8253.counts[0].val ? (TX1_PIT_CLOCK / m_pit8253.counts[0].val) * m_freq_to_step : 0; + step_1 = m_pit8253.counts[1].val ? (TX1_PIT_CLOCK / m_pit8253.counts[1].val) * m_freq_to_step : 0; + step_2 = m_pit8253.counts[2].val ? (TX1_PIT_CLOCK / m_pit8253.counts[2].val) * m_freq_to_step : 0; - //gain_0 = tx1_engine_gains[state->m_ay_outputa & 0xf]; - //gain_1 = tx1_engine_gains[state->m_ay_outputa >> 4]; - gain_2 = tx1_engine_gains[state->m_ay_outputb & 0xf]; - gain_3 = BIT(state->m_ay_outputb, 5) ? 1.0f : 1.5f; + //gain_0 = tx1_engine_gains[m_ay_outputa & 0xf]; + //gain_1 = tx1_engine_gains[m_ay_outputa >> 4]; + gain_2 = tx1_engine_gains[m_ay_outputb & 0xf]; + gain_3 = BIT(m_ay_outputb, 5) ? 1.0f : 1.5f; while (samples--) { - if (state->m_step0 & ((1 << TX1_FRAC))) + if (m_step0 & ((1 << TX1_FRAC))) { - update_engine(state->m_eng0); - state->m_pit0 = combine_4_weights(state->m_weights0, state->m_eng0[0], state->m_eng0[1], state->m_eng0[2], state->m_eng0[3]); - state->m_step0 &= ((1 << TX1_FRAC) - 1); + update_engine(m_eng0); + m_pit0 = combine_4_weights(m_weights0, m_eng0[0], m_eng0[1], m_eng0[2], m_eng0[3]); + m_step0 &= ((1 << TX1_FRAC) - 1); } - if (state->m_step1 & ((1 << TX1_FRAC))) + if (m_step1 & ((1 << TX1_FRAC))) { - update_engine(state->m_eng1); - state->m_pit1 = combine_3_weights(state->m_weights1, state->m_eng1[0], state->m_eng1[1], state->m_eng1[3]); - state->m_step1 &= ((1 << TX1_FRAC) - 1); + update_engine(m_eng1); + m_pit1 = combine_3_weights(m_weights1, m_eng1[0], m_eng1[1], m_eng1[3]); + m_step1 &= ((1 << TX1_FRAC) - 1); } - if (state->m_step2 & ((1 << TX1_FRAC))) + if (m_step2 & ((1 << TX1_FRAC))) { - update_engine(state->m_eng2); - state->m_pit2 = combine_3_weights(state->m_weights2, state->m_eng2[0], state->m_eng2[1], state->m_eng2[3]); - state->m_step2 &= ((1 << TX1_FRAC) - 1); + update_engine(m_eng2); + m_pit2 = combine_3_weights(m_weights2, m_eng2[0], m_eng2[1], m_eng2[3]); + m_step2 &= ((1 << TX1_FRAC) - 1); } - *fl++ = (state->m_pit0 + state->m_pit1)*gain_3 + 2*state->m_pit2*gain_2; - *fr++ = (state->m_pit0 + state->m_pit1)*gain_3 + 2*state->m_pit2*gain_2; + *fl++ = (m_pit0 + m_pit1)*gain_3 + 2*m_pit2*gain_2; + *fr++ = (m_pit0 + m_pit1)*gain_3 + 2*m_pit2*gain_2; - state->m_step0 += step_0; - state->m_step1 += step_1; - state->m_step2 += step_2; + m_step0 += step_0; + m_step1 += step_1; + m_step2 += step_2; } } -static DEVICE_START( tx1_sound ) -{ - tx1_sound_state *state = get_safe_token(device); - running_machine &machine = device->machine(); - static const int r0[4] = { 390e3, 180e3, 180e3, 180e3 }; - static const int r1[3] = { 180e3, 390e3, 56e3 }; - static const int r2[3] = { 390e3, 390e3, 180e3 }; - - - /* Allocate the stream */ - state->m_stream = device->machine().sound().stream_alloc(*device, 0, 2, machine.sample_rate(), NULL, tx1_stream_update); - state->m_freq_to_step = (double)(1 << TX1_FRAC) / (double)machine.sample_rate(); - - /* Compute the engine resistor weights */ - compute_resistor_weights(0, 10000, -1.0, - 4, &r0[0], state->m_weights0, 0, 0, - 3, &r1[0], state->m_weights1, 0, 0, - 3, &r2[0], state->m_weights2, 0, 0); -} - -static DEVICE_RESET( tx1_sound ) -{ - tx1_sound_state *state = get_safe_token(device); - - state->m_step0 = state->m_step1 = state->m_step2 = 0; -} - /************************************* * * Buggy Boy @@ -360,7 +342,64 @@ static const double bb_engine_gains[16] = -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2S + BUGGYBOY_R3S + BUGGYBOY_R4S) + 1.0/100e3)/100e3, }; +const device_type BUGGYBOY = &device_creator<buggyboy_sound_device>; + +buggyboy_sound_device::buggyboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : tx1_sound_device(mconfig, BUGGYBOY, "Buggy Boy Custom", tag, owner, clock, "buggyboy_sound", __FILE__) +{ +} + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void buggyboy_sound_device::device_config_complete() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void buggyboy_sound_device::device_start() +{ + static const int resistors[4] = { 330000, 220000, 330000, 220000 }; + double aweights[4]; + int i; + static const int tmp[16] = + { + 0x0, 0x1, 0xe, 0xf, 0x8, 0x9, 0x6, 0x7, 0xc, 0xd, 0xe, 0xf, 0x4, 0x5, 0x6, 0x7 + }; + + compute_resistor_weights(0, 16384, -1.0, + 4, &resistors[0], aweights, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 ); + for (i = 0; i < 16; i++) + m_eng_voltages[i] = combine_4_weights(aweights, BIT(tmp[i], 0), BIT(tmp[i], 1), BIT(tmp[i], 2), BIT(tmp[i], 3)); + + /* Allocate the stream */ + m_stream = machine().sound().stream_alloc(*this, 0, 2, machine().sample_rate(), this); + m_freq_to_step = (double)(1 << 24) / (double)machine().sample_rate(); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void buggyboy_sound_device::device_reset() +{ + m_step0 = m_step1 = 0; + + /* Reset noise LFSR */ + m_noise_lfsra = 0; + m_noise_lfsrb = 1; + m_noise_lfsrc = 0; + m_noise_lfsrd = 0; +} /*************************************************************************** @@ -399,32 +438,27 @@ static const double bb_engine_gains[16] = ***************************************************************************/ -WRITE8_DEVICE_HANDLER( bb_ym1_a_w ) +WRITE8_MEMBER( buggyboy_sound_device::ym1_a_w ) { - tx1_sound_state *state = get_safe_token(device); - - state->m_stream->update(); - state->m_ym1_outputa = data ^ 0xff; + m_stream->update(); + m_ym1_outputa = data ^ 0xff; } -WRITE8_DEVICE_HANDLER( bb_ym2_a_w ) +WRITE8_MEMBER( buggyboy_sound_device::ym2_a_w ) { - tx1_sound_state *state = get_safe_token(device); - - state->m_stream->update(); - state->m_ym2_outputa = data ^ 0xff; + m_stream->update(); + m_ym2_outputa = data ^ 0xff; } -WRITE8_DEVICE_HANDLER( bb_ym2_b_w ) +WRITE8_MEMBER( buggyboy_sound_device::ym2_b_w ) { - tx1_sound_state *state = get_safe_token(device); device_t *ym1 = space.machine().device("ym1"); device_t *ym2 = space.machine().device("ym2"); double gain; - state->m_stream->update(); + m_stream->update(); - state->m_ym2_outputb = data ^ 0xff; + m_ym2_outputb = data ^ 0xff; if (!strcmp(space.machine().system().name, "buggyboyjr")) { @@ -454,10 +488,15 @@ WRITE8_DEVICE_HANDLER( bb_ym2_b_w ) sound->set_output_gain(2, gain); } -/* This is admittedly a bit of a hack job... */ -static STREAM_UPDATE( buggyboy_stream_update ) + +//------------------------------------------------- +// sound_stream_update - handle a stream update +//------------------------------------------------- + +void buggyboy_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { - tx1_sound_state *state = get_safe_token(device); + /* This is admittedly a bit of a hack job... */ + UINT32 step_0, step_1; int n1_en, n2_en; double gain0, gain1_l, gain1_r; @@ -470,59 +509,59 @@ static STREAM_UPDATE( buggyboy_stream_update ) memset(outputs[1], 0, samples * sizeof(*outputs[1])); /* 8253 outputs for the player/opponent buggy engine sounds. */ - step_0 = state->m_pit8253.counts[0].val ? (BUGGYBOY_PIT_CLOCK / state->m_pit8253.counts[0].val) * state->m_freq_to_step : 0; - step_1 = state->m_pit8253.counts[1].val ? (BUGGYBOY_PIT_CLOCK / state->m_pit8253.counts[1].val) * state->m_freq_to_step : 0; + step_0 = m_pit8253.counts[0].val ? (BUGGYBOY_PIT_CLOCK / m_pit8253.counts[0].val) * m_freq_to_step : 0; + step_1 = m_pit8253.counts[1].val ? (BUGGYBOY_PIT_CLOCK / m_pit8253.counts[1].val) * m_freq_to_step : 0; - if (!strcmp(device->machine().system().name, "buggyboyjr")) - gain0 = BIT(state->m_ym2_outputb, 3) ? 1.0 : 2.0; + if (!strcmp(machine().system().name, "buggyboyjr")) + gain0 = BIT(m_ym2_outputb, 3) ? 1.0 : 2.0; else - gain0 = BIT(state->m_ym1_outputa, 3) ? 1.0 : 2.0; + gain0 = BIT(m_ym1_outputa, 3) ? 1.0 : 2.0; - n1_en = BIT(state->m_ym2_outputb, 4); - n2_en = BIT(state->m_ym2_outputb, 5); + n1_en = BIT(m_ym2_outputb, 4); + n2_en = BIT(m_ym2_outputb, 5); - gain1_l = bb_engine_gains[state->m_ym2_outputa >> 4] * 5; - gain1_r = bb_engine_gains[state->m_ym2_outputa & 0xf] * 5; + gain1_l = bb_engine_gains[m_ym2_outputa >> 4] * 5; + gain1_r = bb_engine_gains[m_ym2_outputa & 0xf] * 5; while (samples--) { int i; stream_sample_t pit0, pit1, n1, n2; - pit0 = state->m_eng_voltages[(state->m_step0 >> 24) & 0xf]; - pit1 = state->m_eng_voltages[(state->m_step1 >> 24) & 0xf]; + pit0 = m_eng_voltages[(m_step0 >> 24) & 0xf]; + pit1 = m_eng_voltages[(m_step1 >> 24) & 0xf]; /* Calculate the tyre screech noise source */ - for (i = 0; i < BUGGYBOY_NOISE_CLOCK / device->machine().sample_rate(); ++i) + for (i = 0; i < BUGGYBOY_NOISE_CLOCK / machine().sample_rate(); ++i) { /* CD4006 is a 4-4-1-4-4-1 shift register */ - int p13 = BIT(state->m_noise_lfsra, 3); - int p12 = BIT(state->m_noise_lfsrb, 4); - int p10 = BIT(state->m_noise_lfsrc, 3); - int p8 = BIT(state->m_noise_lfsrd, 3); + int p13 = BIT(m_noise_lfsra, 3); + int p12 = BIT(m_noise_lfsrb, 4); + int p10 = BIT(m_noise_lfsrc, 3); + int p8 = BIT(m_noise_lfsrd, 3); /* Update the register */ - state->m_noise_lfsra = p12 | ((state->m_noise_lfsra << 1) & 0xf); - state->m_noise_lfsrb = (p8 ^ p12) | ((state->m_noise_lfsrb << 1) & 0x1f); - state->m_noise_lfsrc = p13 | ((state->m_noise_lfsrc << 1) & 0xf); - state->m_noise_lfsrd = p10 | ((state->m_noise_lfsrd << 1) & 0x1f); + m_noise_lfsra = p12 | ((m_noise_lfsra << 1) & 0xf); + m_noise_lfsrb = (p8 ^ p12) | ((m_noise_lfsrb << 1) & 0x1f); + m_noise_lfsrc = p13 | ((m_noise_lfsrc << 1) & 0xf); + m_noise_lfsrd = p10 | ((m_noise_lfsrd << 1) & 0x1f); /* 4040 12-bit counter is clocked on the falling edge of Q13 */ - if ( !BIT(state->m_noise_lfsrc, 3) && p10 ) - state->m_noise_counter = (state->m_noise_counter + 1) & 0x0fff; + if ( !BIT(m_noise_lfsrc, 3) && p10 ) + m_noise_counter = (m_noise_counter + 1) & 0x0fff; } if (n1_en) { - n1 = !BIT(state->m_noise_counter, 7-1) * 16000; - if ( BIT(state->m_noise_counter, 11-1) ) n1 /=2; + n1 = !BIT(m_noise_counter, 7-1) * 16000; + if ( BIT(m_noise_counter, 11-1) ) n1 /=2; } else n1 = 8192; if (n2_en) { - n2 = !BIT(state->m_noise_counter, 6-1) * 16000; - if ( BIT(state->m_noise_counter, 11-1) ) n2 /=2; + n2 = !BIT(m_noise_counter, 6-1) * 16000; + if ( BIT(m_noise_counter, 11-1) ) n2 /=2; } else n2 = 8192; @@ -530,144 +569,7 @@ static STREAM_UPDATE( buggyboy_stream_update ) *fl++ = n1 + n2 + (pit0 * gain0) + (pit1 * gain1_l); *fr++ = n1 + n2 + (pit0 * gain0) + (pit1 * gain1_r); - state->m_step0 += step_0; - state->m_step1 += step_1; + m_step0 += step_0; + m_step1 += step_1; } -} - -static DEVICE_START( buggyboy_sound ) -{ - tx1_sound_state *state = get_safe_token(device); - running_machine &machine = device->machine(); - static const int resistors[4] = { 330000, 220000, 330000, 220000 }; - double aweights[4]; - int i; - static const int tmp[16] = - { - 0x0, 0x1, 0xe, 0xf, 0x8, 0x9, 0x6, 0x7, 0xc, 0xd, 0xe, 0xf, 0x4, 0x5, 0x6, 0x7 - }; - - compute_resistor_weights(0, 16384, -1.0, - 4, &resistors[0], aweights, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 ); - - for (i = 0; i < 16; i++) - state->m_eng_voltages[i] = combine_4_weights(aweights, BIT(tmp[i], 0), BIT(tmp[i], 1), BIT(tmp[i], 2), BIT(tmp[i], 3)); - - /* Allocate the stream */ - state->m_stream = device->machine().sound().stream_alloc(*device, 0, 2, machine.sample_rate(), NULL, buggyboy_stream_update); - state->m_freq_to_step = (double)(1 << 24) / (double)machine.sample_rate(); -} - -static DEVICE_RESET( buggyboy_sound ) -{ - tx1_sound_state *state = get_safe_token(device); - - state->m_step0 = state->m_step1 = 0; - - /* Reset noise LFSR */ - state->m_noise_lfsra = 0; - state->m_noise_lfsrb = 1; - state->m_noise_lfsrc = 0; - state->m_noise_lfsrd = 0; -} - -const device_type BUGGYBOY = &device_creator<buggyboy_sound_device>; - -buggyboy_sound_device::buggyboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : tx1_sound_device(mconfig, BUGGYBOY, "Buggy Boy Custom", tag, owner, clock, "buggyboy_sound", __FILE__) -{ -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void buggyboy_sound_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void buggyboy_sound_device::device_start() -{ - DEVICE_START_NAME( buggyboy_sound )(this); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void buggyboy_sound_device::device_reset() -{ - DEVICE_RESET_NAME( buggyboy_sound )(this); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void buggyboy_sound_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"); -} - - -const device_type TX1 = &device_creator<tx1_sound_device>; - -tx1_sound_device::tx1_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, TX1, "TX-1 Custom", tag, owner, clock, "tx1_sound", __FILE__), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(tx1_sound_state); -} - -tx1_sound_device::tx1_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) - : device_t(mconfig, type, name, tag, owner, clock, shortname, source), - device_sound_interface(mconfig, *this) -{ - m_token = global_alloc_clear(tx1_sound_state); -} -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void tx1_sound_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void tx1_sound_device::device_start() -{ - DEVICE_START_NAME( tx1_sound )(this); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void tx1_sound_device::device_reset() -{ - DEVICE_RESET_NAME( tx1_sound )(this); -} - -//------------------------------------------------- -// sound_stream_update - handle a stream update -//------------------------------------------------- - -void tx1_sound_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"); -} +}
\ No newline at end of file diff --git a/src/mame/drivers/tx1.c b/src/mame/drivers/tx1.c index a995ad1f9de..30e2efde1d8 100644 --- a/src/mame/drivers/tx1.c +++ b/src/mame/drivers/tx1.c @@ -534,7 +534,7 @@ static ADDRESS_MAP_START( tx1_sound_prg, AS_PROGRAM, 8, tx1_state ) AM_RANGE(0x3000, 0x37ff) AM_RAM AM_MIRROR(0x800) AM_SHARE("z80_ram") AM_RANGE(0x4000, 0x4000) AM_WRITE(z80_intreq_w) AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255", i8255_device, read, write) - AM_RANGE(0x6000, 0x6003) AM_DEVREADWRITE_LEGACY("tx1", tx1_pit8253_r, tx1_pit8253_w) + AM_RANGE(0x6000, 0x6003) AM_DEVREADWRITE("tx1", tx1_sound_device, pit8253_r, pit8253_w) AM_RANGE(0x7000, 0x7fff) AM_WRITE(tx1_ppi_latch_w) AM_RANGE(0xb000, 0xbfff) AM_READWRITE(ts_r, ts_w) ADDRESS_MAP_END @@ -598,7 +598,7 @@ static ADDRESS_MAP_START( buggyboy_sound_prg, AS_PROGRAM, 8, tx1_state ) AM_RANGE(0x4000, 0x47ff) AM_RAM AM_SHARE("z80_ram") AM_RANGE(0x6000, 0x6001) AM_READ(bb_analog_r) AM_RANGE(0x6800, 0x6803) AM_DEVREADWRITE("ppi8255", i8255_device, read, write) - AM_RANGE(0x7000, 0x7003) AM_DEVREADWRITE_LEGACY("buggyboy", tx1_pit8253_r, tx1_pit8253_w) + AM_RANGE(0x7000, 0x7003) AM_DEVREADWRITE("buggyboy", buggyboy_sound_device, pit8253_r, pit8253_w) AM_RANGE(0x7800, 0x7800) AM_WRITE(z80_intreq_w) AM_RANGE(0xc000, 0xc7ff) AM_READWRITE(ts_r, ts_w) ADDRESS_MAP_END @@ -607,7 +607,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( buggybjr_sound_prg, AS_PROGRAM, 8, tx1_state ) AM_RANGE(0x0000, 0x3fff) AM_ROM AM_RANGE(0x4000, 0x47ff) AM_RAM AM_SHARE("z80_ram") - AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE_LEGACY("buggyboy", tx1_pit8253_r, tx1_pit8253_w) + AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("buggyboy", buggyboy_sound_device, pit8253_r, pit8253_w) AM_RANGE(0x6000, 0x6001) AM_READ(bbjr_analog_r) AM_RANGE(0x7000, 0x7000) AM_WRITE(z80_intreq_w) AM_RANGE(0xc000, 0xc7ff) AM_READWRITE(ts_r, ts_w) @@ -635,8 +635,8 @@ static const ay8910_interface tx1_ay8910_interface = AY8910_DEFAULT_LOADS, DEVCB_NULL, DEVCB_NULL, - DEVCB_DEVICE_HANDLER("tx1", tx1_ay8910_a_w), - DEVCB_DEVICE_HANDLER("tx1", tx1_ay8910_b_w), + DEVCB_DEVICE_MEMBER("tx1", tx1_sound_device, ay8910_a_w), + DEVCB_DEVICE_MEMBER("tx1", tx1_sound_device, ay8910_b_w), }; @@ -646,7 +646,7 @@ static const ay8910_interface buggyboy_ym2149_interface_1 = AY8910_DEFAULT_LOADS, DEVCB_NULL, DEVCB_NULL, - DEVCB_DEVICE_HANDLER("buggyboy", bb_ym1_a_w), + DEVCB_DEVICE_MEMBER("buggyboy", buggyboy_sound_device, ym1_a_w), DEVCB_NULL, }; @@ -656,8 +656,8 @@ static const ay8910_interface buggyboy_ym2149_interface_2 = AY8910_DEFAULT_LOADS, DEVCB_NULL, DEVCB_NULL, - DEVCB_DEVICE_HANDLER("buggyboy", bb_ym2_a_w), - DEVCB_DEVICE_HANDLER("buggyboy", bb_ym2_b_w), + DEVCB_DEVICE_MEMBER("buggyboy", buggyboy_sound_device, ym2_a_w), + DEVCB_DEVICE_MEMBER("buggyboy", buggyboy_sound_device, ym2_b_w), }; @@ -679,8 +679,8 @@ static const ay8910_interface buggybjr_ym2149_interface_2 = AY8910_DEFAULT_LOADS, DEVCB_NULL, DEVCB_NULL, - DEVCB_DEVICE_HANDLER("buggyboy", bb_ym2_a_w), - DEVCB_DEVICE_HANDLER("buggyboy", bb_ym2_b_w), + DEVCB_DEVICE_MEMBER("buggyboy", buggyboy_sound_device, ym2_a_w), + DEVCB_DEVICE_MEMBER("buggyboy", buggyboy_sound_device, ym2_b_w), }; diff --git a/src/mame/includes/tx1.h b/src/mame/includes/tx1.h index 9ef1c438d6d..5cf71703b4c 100644 --- a/src/mame/includes/tx1.h +++ b/src/mame/includes/tx1.h @@ -213,16 +213,26 @@ public: }; /*----------- defined in audio/tx1.c -----------*/ -DECLARE_READ8_DEVICE_HANDLER( tx1_pit8253_r ); -DECLARE_WRITE8_DEVICE_HANDLER( tx1_pit8253_w ); -DECLARE_WRITE8_DEVICE_HANDLER( bb_ym1_a_w ); -DECLARE_WRITE8_DEVICE_HANDLER( bb_ym2_a_w ); -DECLARE_WRITE8_DEVICE_HANDLER( bb_ym2_b_w ); - - -DECLARE_WRITE8_DEVICE_HANDLER( tx1_ay8910_a_w ); -DECLARE_WRITE8_DEVICE_HANDLER( tx1_ay8910_b_w ); +/************************************* + * + * 8253 Programmable Interval Timer + * + *************************************/ +struct pit8253_state +{ + union + { +#ifdef LSB_FIRST + struct { UINT8 LSB; UINT8 MSB; }; +#else + struct { UINT8 MSB; UINT8 LSB; }; +#endif + UINT16 val; + } counts[3]; + + int idx[3]; +}; class tx1_sound_device : public device_t, public device_sound_interface @@ -230,10 +240,13 @@ class tx1_sound_device : public device_t, public: tx1_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); tx1_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); - ~tx1_sound_device() { global_free(m_token); } + ~tx1_sound_device() {} - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } + DECLARE_READ8_MEMBER( pit8253_r ); + DECLARE_WRITE8_MEMBER( pit8253_w ); + DECLARE_WRITE8_MEMBER( ay8910_a_w ); + DECLARE_WRITE8_MEMBER( ay8910_b_w ); + protected: // device-level overrides virtual void device_config_complete(); @@ -242,9 +255,39 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); -private: + // internal state - void *m_token; + sound_stream *m_stream; + UINT32 m_freq_to_step; + UINT32 m_step0; + UINT32 m_step1; + UINT32 m_step2; + + pit8253_state m_pit8253; + + UINT8 m_ay_outputa; + UINT8 m_ay_outputb; + + stream_sample_t m_pit0; + stream_sample_t m_pit1; + stream_sample_t m_pit2; + + double m_weights0[4]; + double m_weights1[3]; + double m_weights2[3]; + int m_eng0[4]; + int m_eng1[4]; + int m_eng2[4]; + + int m_noise_lfsra; + int m_noise_lfsrb; + int m_noise_lfsrc; + int m_noise_lfsrd; + int m_noise_counter; + UINT8 m_ym1_outputa; + UINT8 m_ym2_outputa; + UINT8 m_ym2_outputb; + UINT16 m_eng_voltages[16]; }; extern const device_type TX1; @@ -253,6 +296,11 @@ class buggyboy_sound_device : public tx1_sound_device { public: buggyboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + DECLARE_WRITE8_MEMBER( ym1_a_w ); + DECLARE_WRITE8_MEMBER( ym2_a_w ); + DECLARE_WRITE8_MEMBER( ym2_b_w ); + protected: // device-level overrides virtual void device_config_complete(); @@ -261,6 +309,7 @@ protected: // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); + private: // internal state }; |