summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/segasnd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/audio/segasnd.cpp')
-rw-r--r--src/mame/audio/segasnd.cpp909
1 files changed, 0 insertions, 909 deletions
diff --git a/src/mame/audio/segasnd.cpp b/src/mame/audio/segasnd.cpp
deleted file mode 100644
index af247149188..00000000000
--- a/src/mame/audio/segasnd.cpp
+++ /dev/null
@@ -1,909 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- segasnd.cpp
-
- Sound boards for early Sega G-80 based games.
-
-***************************************************************************/
-
-#include "emu.h"
-#include "segasnd.h"
-
-#include "sound/sp0250.h"
-#include "includes/segag80r.h"
-#include "includes/segag80v.h"
-
-#include <cmath>
-
-
-#define VERBOSE 0
-#include "logmacro.h"
-
-
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-#define SPEECH_MASTER_CLOCK 3120000
-
-#define USB_MASTER_CLOCK 6000000
-#define USB_2MHZ_CLOCK (USB_MASTER_CLOCK/3)
-#define USB_PCS_CLOCK (USB_2MHZ_CLOCK/2)
-#define USB_GOS_CLOCK (USB_2MHZ_CLOCK/16/4)
-#define MM5837_CLOCK 100000
-
-#define SAMPLE_RATE (USB_2MHZ_CLOCK/8)
-
-
-
-/***************************************************************************
- INLINE FUNCTIONS
-***************************************************************************/
-
-inline void usb_sound_device::g80_filter_state::configure(double r, double c)
-{
- capval = 0.0;
- exponent = 1.0 - std::exp(-1.0 / (r * c * SAMPLE_RATE));
-}
-
-
-inline double usb_sound_device::g80_filter_state::step_rc(double input)
-{
- return capval += (input - capval) * exponent;
-}
-
-
-inline double usb_sound_device::g80_filter_state::step_cr(double input)
-{
- double const result = input - capval;
- capval += result * exponent;
- return result;
-}
-
-
-
-/***************************************************************************
- SPEECH BOARD
-***************************************************************************/
-
-DEFINE_DEVICE_TYPE(SEGASPEECH, speech_sound_device, "sega_speech_sound", "Sega Speech Sound Board")
-
-#define SEGASPEECH_REGION "speech"
-
-speech_sound_device::speech_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, SEGASPEECH, tag, owner, clock),
- device_sound_interface(mconfig, *this),
- m_int_cb(*this),
- m_speech(*this, SEGASPEECH_REGION),
- m_drq(0),
- m_latch(0),
- m_t0(0),
- m_p2(0)
-{
-}
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void speech_sound_device::device_start()
-{
- m_int_cb.resolve();
-
- save_item(NAME(m_latch));
- save_item(NAME(m_t0));
- save_item(NAME(m_p2));
- save_item(NAME(m_drq));
-}
-
-
-/*************************************
- *
- * i8035 port accessors
- *
- *************************************/
-
-
-
-READ_LINE_MEMBER( speech_sound_device::t0_r )
-{
- return m_t0;
-}
-
-READ_LINE_MEMBER( speech_sound_device::t1_r )
-{
- return m_drq;
-}
-
-uint8_t speech_sound_device::p1_r()
-{
- return m_latch & 0x7f;
-}
-
-uint8_t speech_sound_device::rom_r(offs_t offset)
-{
- return m_speech->base()[0x100 * (m_p2 & 0x3f) + offset];
-}
-
-void speech_sound_device::p1_w(uint8_t data)
-{
- if (!(data & 0x80))
- m_t0 = 0;
-}
-
-void speech_sound_device::p2_w(uint8_t data)
-{
- m_p2 = data;
-}
-
-
-
-/*************************************
- *
- * i8035 port accessors
- *
- *************************************/
-
-WRITE_LINE_MEMBER(speech_sound_device::drq_w)
-{
- m_drq = (state == ASSERT_LINE);
-}
-
-
-
-/*************************************
- *
- * External access
- *
- *************************************/
-
-TIMER_CALLBACK_MEMBER( speech_sound_device::delayed_speech_w )
-{
- int data = param;
- u8 old = m_latch;
-
- /* all 8 bits are latched */
- m_latch = data;
-
- /* the high bit goes directly to the INT line */
- m_int_cb((data & 0x80) ? CLEAR_LINE : ASSERT_LINE);
-
- /* a clock on the high bit clocks a 1 into T0 */
- if (!(old & 0x80) && (data & 0x80))
- m_t0 = 1;
-}
-
-
-void speech_sound_device::data_w(uint8_t data)
-{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(speech_sound_device::delayed_speech_w), this), data);
-}
-
-
-void speech_sound_device::control_w(uint8_t data)
-{
- LOG("Speech control = %X\n", data);
-}
-
-
-//-------------------------------------------------
-// sound_stream_update - handle a stream update
-//-------------------------------------------------
-
-void speech_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
-{
-}
-
-/*************************************
- *
- * Speech board functions
- *
- *************************************/
-
-WRITE_LINE_MEMBER(segag80snd_common::segaspeech_int_w)
-{
- m_audiocpu->set_input_line(0, state);
-}
-
-/*************************************
- *
- * Speech board address maps
- *
- *************************************/
-
-void segag80snd_common::speech_map(address_map &map)
-{
- map(0x0000, 0x07ff).mirror(0x0800).rom();
-}
-
-
-void segag80snd_common::speech_portmap(address_map &map)
-{
- map(0x00, 0xff).r("segaspeech", FUNC(speech_sound_device::rom_r));
- map(0x00, 0xff).w("speech", FUNC(sp0250_device::write));
-}
-
-
-/*************************************
- *
- * Speech board machine drivers
- *
- *************************************/
-
-void segag80snd_common::sega_speech_board(machine_config &config)
-{
- /* CPU for the speech board */
- i8035_device &audiocpu(I8035(config, m_audiocpu, SPEECH_MASTER_CLOCK)); /* divide by 15 in CPU */
- audiocpu.set_addrmap(AS_PROGRAM, &segag80snd_common::speech_map);
- audiocpu.set_addrmap(AS_IO, &segag80snd_common::speech_portmap);
- audiocpu.p1_in_cb().set("segaspeech", FUNC(speech_sound_device::p1_r));
- audiocpu.p1_out_cb().set("segaspeech", FUNC(speech_sound_device::p1_w));
- audiocpu.p2_out_cb().set("segaspeech", FUNC(speech_sound_device::p2_w));
- audiocpu.t0_in_cb().set("segaspeech", FUNC(speech_sound_device::t0_r));
- audiocpu.t1_in_cb().set("segaspeech", FUNC(speech_sound_device::t1_r));
-
- /* sound hardware */
- SEGASPEECH(config, "segaspeech", 0).int_cb().set(FUNC(segag80snd_common::segaspeech_int_w));
- sp0250_device &speech(SP0250(config, "speech", SPEECH_MASTER_CLOCK));
- speech.drq().set("segaspeech", FUNC(speech_sound_device::drq_w));
- speech.add_route(ALL_OUTPUTS, "speaker", 1.0);
-}
-
-
-
-/***************************************************************************
- UNIVERSAL SOUND BOARD
-***************************************************************************/
-
-DEFINE_DEVICE_TYPE(SEGAUSB, usb_sound_device, "segausb", "Sega Universal Sound Board")
-
-usb_sound_device::usb_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, type, tag, owner, clock),
- device_sound_interface(mconfig, *this),
- m_ourcpu(*this, "ourcpu"),
- m_maincpu(*this, finder_base::DUMMY_TAG),
- m_stream(nullptr),
- m_in_latch(0),
- m_out_latch(0),
- m_last_p2_value(0),
- m_program_ram(*this, "pgmram"),
- m_work_ram(*this, "workram"),
- m_work_ram_bank(0),
- m_t1_clock(0),
- m_t1_clock_mask(0),
- m_noise_shift(0),
- m_noise_state(0),
- m_noise_subcount(0)
-{
-}
-
-usb_sound_device::usb_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : usb_sound_device(mconfig, SEGAUSB, tag, owner, clock)
-{
-}
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void usb_sound_device::device_start()
-{
- /* create a sound stream */
- m_stream = machine().sound().stream_alloc(*this, 0, 1, SAMPLE_RATE);
-
- /* initialize state */
- m_noise_shift = 0x15555;
-
- for (timer8253 &g : m_timer_group)
- {
- g.chan_filter[0].configure(10e3, 1e-6);
- g.chan_filter[1].configure(10e3, 1e-6);
- g.gate1.configure(100e3, 0.01e-6);
- g.gate2.configure(2 * 100e3, 0.01e-6);
- }
-
- g80_filter_state temp;
- temp.configure(100e3, 0.01e-6);
- m_gate_rc1_exp[0] = temp.exponent;
- temp.configure(1e3, 0.01e-6);
- m_gate_rc1_exp[1] = temp.exponent;
- temp.configure(2 * 100e3, 0.01e-6);
- m_gate_rc2_exp[0] = temp.exponent;
- temp.configure(2 * 1e3, 0.01e-6);
- m_gate_rc2_exp[1] = temp.exponent;
-
- m_noise_filters[0].configure(2.7e3 + 2.7e3, 1.0e-6);
- m_noise_filters[1].configure(2.7e3 + 1e3, 0.30e-6);
- m_noise_filters[2].configure(2.7e3 + 270, 0.15e-6);
- m_noise_filters[3].configure(2.7e3 + 0, 0.082e-6);
- m_noise_filters[4].configure(33e3, 0.1e-6);
-
- m_final_filter.configure(100e3, 4.7e-6);
-
- /* register for save states */
- save_item(NAME(m_in_latch));
- save_item(NAME(m_out_latch));
- save_item(NAME(m_last_p2_value));
- save_item(NAME(m_work_ram_bank));
- save_item(NAME(m_t1_clock));
-
- for (int tgroup = 0; tgroup < 3; tgroup++)
- {
- timer8253 *group = &m_timer_group[tgroup];
- for (int tchan = 0; tchan < 3; tchan++)
- {
- timer8253::channel *channel = &group->chan[tchan];
- save_item(NAME(channel->holding), tgroup * 3 + tchan);
- save_item(NAME(channel->latchmode), tgroup * 3 + tchan);
- save_item(NAME(channel->latchtoggle), tgroup * 3 + tchan);
- save_item(NAME(channel->clockmode), tgroup * 3 + tchan);
- save_item(NAME(channel->bcdmode), tgroup * 3 + tchan);
- save_item(NAME(channel->output), tgroup * 3 + tchan);
- save_item(NAME(channel->lastgate), tgroup * 3 + tchan);
- save_item(NAME(channel->gate), tgroup * 3 + tchan);
- save_item(NAME(channel->subcount), tgroup * 3 + tchan);
- save_item(NAME(channel->count), tgroup * 3 + tchan);
- save_item(NAME(channel->remain), tgroup * 3 + tchan);
- }
- save_item(NAME(group->env), tgroup);
- save_item(NAME(group->chan_filter[0].capval), tgroup);
- save_item(NAME(group->chan_filter[1].capval), tgroup);
- save_item(NAME(group->gate1.capval), tgroup);
- save_item(NAME(group->gate2.capval), tgroup);
- save_item(NAME(group->config), tgroup);
- }
-
- save_item(NAME(m_timer_mode));
- save_item(NAME(m_noise_shift));
- save_item(NAME(m_noise_state));
- save_item(NAME(m_noise_subcount));
- save_item(NAME(m_final_filter.capval));
- save_item(NAME(m_noise_filters[0].capval));
- save_item(NAME(m_noise_filters[1].capval));
- save_item(NAME(m_noise_filters[2].capval));
- save_item(NAME(m_noise_filters[3].capval));
- save_item(NAME(m_noise_filters[4].capval));
-}
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void usb_sound_device::device_reset()
-{
- /* halt the USB CPU at reset time */
- m_ourcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
-
- /* start the clock timer */
- m_t1_clock_mask = 0x10;
-}
-
-/*************************************
- *
- * Initialization/reset
- *
- *************************************/
-
-TIMER_DEVICE_CALLBACK_MEMBER( usb_sound_device::increment_t1_clock_timer_cb )
-{
- /* only increment if it is not being forced clear */
- if (!(m_last_p2_value & 0x80))
- m_t1_clock++;
-}
-
-/*************************************
- *
- * External access
- *
- *************************************/
-
-uint8_t usb_sound_device::status_r()
-{
- LOG("%s:usb_data_r = %02X\n", machine().describe_context(), (m_out_latch & 0x81) | (m_in_latch & 0x7e));
-
- m_maincpu->adjust_icount(-200);
-
- /* only bits 0 and 7 are controlled by the I8035; the remaining */
- /* bits 1-6 reflect the current input latch values */
- return (m_out_latch & 0x81) | (m_in_latch & 0x7e);
-}
-
-
-TIMER_CALLBACK_MEMBER( usb_sound_device::delayed_usb_data_w )
-{
- int data = param;
-
- /* look for rising/falling edges of bit 7 to control the RESET line */
- m_ourcpu->set_input_line(INPUT_LINE_RESET, (data & 0x80) ? ASSERT_LINE : CLEAR_LINE);
-
- /* if the CLEAR line is set, the low 7 bits of the input are ignored */
- if ((m_last_p2_value & 0x40) == 0)
- data &= ~0x7f;
-
- /* update the effective input latch */
- m_in_latch = data;
-}
-
-
-void usb_sound_device::data_w(uint8_t data)
-{
- LOG("%s:usb_data_w = %02X\n", machine().describe_context(), data);
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(usb_sound_device::delayed_usb_data_w), this), data);
-
- /* boost the interleave so that sequences can be sent */
- machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(250));
-}
-
-
-uint8_t usb_sound_device::ram_r(offs_t offset)
-{
- return m_program_ram[offset];
-}
-
-
-void usb_sound_device::ram_w(offs_t offset, uint8_t data)
-{
- if (m_in_latch & 0x80)
- m_program_ram[offset] = data;
- else
- LOG("%s:sega_usb_ram_w(%03X) = %02X while /LOAD disabled\n", machine().describe_context(), offset, data);
-}
-
-
-
-/*************************************
- *
- * I8035 port accesses
- *
- *************************************/
-
-uint8_t usb_sound_device::p1_r()
-{
- /* bits 0-6 are inputs and map to bits 0-6 of the input latch */
- if ((m_in_latch & 0x7f) != 0)
- LOG("%s: P1 read = %02X\n", machine().describe_context(), m_in_latch & 0x7f);
- return m_in_latch & 0x7f;
-}
-
-
-void usb_sound_device::p1_w(uint8_t data)
-{
- /* bit 7 maps to bit 0 on the output latch */
- m_out_latch = (m_out_latch & 0xfe) | (data >> 7);
- LOG("%s: P1 write = %02X\n", machine().describe_context(), data);
-}
-
-
-void usb_sound_device::p2_w(uint8_t data)
-{
- u8 old = m_last_p2_value;
- m_last_p2_value = data;
-
- /* low 2 bits control the bank of work RAM we are addressing */
- m_work_ram_bank = data & 3;
-
- /* bit 6 controls the "ready" bit output to the host */
- /* it also clears the input latch from the host (active low) */
- m_out_latch = ((data & 0x40) << 1) | (m_out_latch & 0x7f);
- if ((data & 0x40) == 0)
- m_in_latch = 0;
-
- /* bit 7 controls the reset on the upper counter at U33 */
- if ((old & 0x80) && !(data & 0x80))
- m_t1_clock = 0;
-
- LOG("%s: P2 write -> bank=%d ready=%d clock=%d\n", machine().describe_context(), data & 3, (data >> 6) & 1, (data >> 7) & 1);
-}
-
-
-READ_LINE_MEMBER( usb_sound_device::t1_r )
-{
- /* T1 returns 1 based on the value of the T1 clock; the exact */
- /* pattern is determined by one or more jumpers on the board. */
- return (m_t1_clock & m_t1_clock_mask) != 0;
-}
-
-
-
-/*************************************
- *
- * Sound generation
- *
- *************************************/
-
-inline void usb_sound_device::timer8253::channel::clock()
-{
- u8 const old_lastgate = lastgate;
-
- /* update the gate */
- lastgate = gate;
-
- /* if we're holding, skip */
- if (holding)
- return;
-
- /* switch off the clock mode */
- switch (clockmode)
- {
- /* oneshot; waits for trigger to restart */
- case 1:
- if (!old_lastgate && gate)
- {
- output = 0;
- remain = count;
- }
- else
- {
- if (--remain == 0)
- output = 1;
- }
- break;
-
- /* square wave: counts down by 2 and toggles output */
- case 3:
- remain = (remain - 1) & ~1;
- if (remain == 0)
- {
- output ^= 1;
- remain = count;
- }
- break;
- }
-}
-
-
-/*************************************
- *
- * USB timer and envelope controls
- *
- *************************************/
-
-void usb_sound_device::timer_w(int which, u8 offset, u8 data)
-{
- timer8253 *g = &m_timer_group[which];
- timer8253::channel *ch;
- int was_holding;
-
- m_stream->update();
-
- /* switch off the offset */
- switch (offset)
- {
- case 0:
- case 1:
- case 2:
- ch = &g->chan[offset];
- was_holding = ch->holding;
-
- /* based on the latching mode */
- switch (ch->latchmode)
- {
- case 1: /* low word only */
- ch->count = data;
- ch->holding = false;
- break;
-
- case 2: /* high word only */
- ch->count = data << 8;
- ch->holding = false;
- break;
-
- case 3: /* low word followed by high word */
- if (ch->latchtoggle == 0)
- {
- ch->count = (ch->count & 0xff00) | (data & 0x00ff);
- ch->latchtoggle = 1;
- }
- else
- {
- ch->count = (ch->count & 0x00ff) | (data << 8);
- ch->holding = false;
- ch->latchtoggle = 0;
- }
- break;
- }
-
- /* if we're not holding, load the initial count for some modes */
- if (was_holding && !ch->holding)
- ch->remain = 1;
- break;
-
- case 3:
- /* break out the components */
- if (((data & 0xc0) >> 6) < 3)
- {
- ch = &g->chan[(data & 0xc0) >> 6];
-
- /* extract the bits */
- ch->holding = true;
- ch->latchmode = (data >> 4) & 3;
- ch->clockmode = (data >> 1) & 7;
- ch->bcdmode = (data >> 0) & 1;
- ch->latchtoggle = 0;
- ch->output = (ch->clockmode == 1);
- }
- break;
- }
-}
-
-
-void usb_sound_device::env_w(int which, u8 offset, u8 data)
-{
- timer8253 *g = &m_timer_group[which];
-
- m_stream->update();
-
- if (offset < 3)
- g->env[offset] = (double)data;
- else
- g->config = data & 1;
-}
-
-
-
-/*************************************
- *
- * USB work RAM access
- *
- *************************************/
-
-uint8_t usb_sound_device::workram_r(offs_t offset)
-{
- offset += 256 * m_work_ram_bank;
- return m_work_ram[offset];
-}
-
-
-void usb_sound_device::workram_w(offs_t offset, uint8_t data)
-{
- offset += 256 * m_work_ram_bank;
- m_work_ram[offset] = data;
-
- /* writes to the low 32 bytes go to various controls */
- switch (offset & ~3)
- {
- case 0x00: /* CTC0 */
- timer_w(0, offset & 3, data);
- break;
-
- case 0x04: /* ENV0 */
- env_w(0, offset & 3, data);
- break;
-
- case 0x08: /* CTC1 */
- timer_w(1, offset & 3, data);
- break;
-
- case 0x0c: /* ENV1 */
- env_w(1, offset & 3, data);
- break;
-
- case 0x10: /* CTC2 */
- timer_w(2, offset & 3, data);
- break;
-
- case 0x14: /* ENV2 */
- env_w(2, offset & 3, data);
- break;
- }
-}
-
-//-------------------------------------------------
-// sound_stream_update - handle a stream update
-//-------------------------------------------------
-
-void usb_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
-{
- stream_sample_t *dest = outputs[0];
-
- /* iterate over samples */
- while (samples--)
- {
- double noiseval;
- double sample = 0;
- int group;
- int step;
-
-
- /*----------------
- Noise Source
- ----------------
-
- RC
- MM5837 ---> FILTER ---> CR FILTER ---> 3.2x AMP ---> NOISE
- LADDER
- */
-
- /* update the noise source */
- for (step = USB_2MHZ_CLOCK / SAMPLE_RATE; step >= m_noise_subcount; step -= m_noise_subcount)
- {
- m_noise_shift = (m_noise_shift << 1) | (((m_noise_shift >> 13) ^ (m_noise_shift >> 16)) & 1);
- m_noise_state = (m_noise_shift >> 16) & 1;
- m_noise_subcount = USB_2MHZ_CLOCK / MM5837_CLOCK;
- }
- m_noise_subcount -= step;
-
- /* update the filtered noise value -- this is just an approximation to the pink noise filter */
- /* being applied on the PCB, but it sounds pretty close */
- m_noise_filters[0].capval = 0.99765 * m_noise_filters[0].capval + m_noise_state * 0.0990460;
- m_noise_filters[1].capval = 0.96300 * m_noise_filters[1].capval + m_noise_state * 0.2965164;
- m_noise_filters[2].capval = 0.57000 * m_noise_filters[2].capval + m_noise_state * 1.0526913;
- noiseval = m_noise_filters[0].capval + m_noise_filters[1].capval + m_noise_filters[2].capval + m_noise_state * 0.1848;
-
- /* final output goes through a CR filter; the scaling factor is arbitrary to get the noise to the */
- /* correct relative volume */
- noiseval = m_noise_filters[4].step_cr(noiseval);
- noiseval *= 0.075;
-
- /* there are 3 identical groups of circuits, each with its own 8253 */
- for (group = 0; group < 3; group++)
- {
- timer8253 *g = &m_timer_group[group];
- double chan0, chan1, chan2, mix;
-
-
- /*-------------
- Channel 0
- -------------
-
- 8253 CR AD7524
- OUT0 ---> FILTER ---> BUFFER---> VRef ---> 100k ---> mix
- */
-
- /* channel 0 clocks with the PCS clock */
- for (step = USB_2MHZ_CLOCK / SAMPLE_RATE; step >= g->chan[0].subcount; step -= g->chan[0].subcount)
- {
- g->chan[0].subcount = USB_2MHZ_CLOCK / USB_PCS_CLOCK;
- g->chan[0].gate = 1;
- g->chan[0].clock();
- }
- g->chan[0].subcount -= step;
-
- /* channel 0 is mixed in with a resistance of 100k */
- chan0 = g->chan_filter[0].step_cr(g->chan[0].output) * g->env[0] * (1.0/100.0);
-
-
- /*-------------
- Channel 1
- -------------
-
- 8253 CR AD7524
- OUT1 ---> FILTER ---> BUFFER---> VRef ---> 100k ---> mix
- */
-
- /* channel 1 clocks with the PCS clock */
- for (step = USB_2MHZ_CLOCK / SAMPLE_RATE; step >= g->chan[1].subcount; step -= g->chan[1].subcount)
- {
- g->chan[1].subcount = USB_2MHZ_CLOCK / USB_PCS_CLOCK;
- g->chan[1].gate = 1;
- g->chan[1].clock();
- }
- g->chan[1].subcount -= step;
-
- /* channel 1 is mixed in with a resistance of 100k */
- chan1 = g->chan_filter[1].step_cr(g->chan[1].output) * g->env[1] * (1.0/100.0);
-
-
- /*-------------
- Channel 2
- -------------
-
- If timer_mode == 0:
-
- SWITCHED AD7524
- NOISE ---> RC ---> 1.56x AMP ---> INVERTER ---> VRef ---> 33k ---> mix
- FILTERS
-
- If timer mode == 1:
-
- AD7524 SWITCHED
- NOISE ---> INVERTER ---> VRef ---> 33k ---> mix ---> INVERTER ---> RC ---> 1.56x AMP ---> finalmix
- FILTERS
- */
-
- /* channel 2 clocks with the 2MHZ clock and triggers with the GOS clock */
- for (step = 0; step < USB_2MHZ_CLOCK / SAMPLE_RATE; step++)
- {
- if (g->chan[2].subcount-- == 0)
- {
- g->chan[2].subcount = USB_2MHZ_CLOCK / USB_GOS_CLOCK / 2 - 1;
- g->chan[2].gate = !g->chan[2].gate;
- }
- g->chan[2].clock();
- }
-
- /* the exponents for the gate filters are determined by channel 2's output */
- g->gate1.exponent = m_gate_rc1_exp[g->chan[2].output];
- g->gate2.exponent = m_gate_rc2_exp[g->chan[2].output];
-
- /* based on the envelope mode, we do one of two things with source 2 */
- if (g->config == 0)
- {
- chan2 = g->gate2.step_rc(g->gate1.step_rc(noiseval)) * -1.56 * g->env[2] * (1.0/33.0);
- mix = chan0 + chan1 + chan2;
- }
- else
- {
- chan2 = -noiseval * g->env[2] * (1.0/33.0);
- mix = chan0 + chan1 + chan2;
- mix = g->gate2.step_rc(g->gate1.step_rc(-mix)) * 1.56;
- }
-
- /* accumulate the sample */
- sample += mix;
- }
-
-
- /*-------------
- Final mix
- -------------
-
- INPUTS
- EQUAL ---> 1.2x INVERTER ---> CR FILTER ---> out
- WEIGHT
-
- */
- *dest++ = 4000 * m_final_filter.step_cr(sample);
- }
-}
-
-
-/*************************************
- *
- * USB address maps
- *
- *************************************/
-
-void usb_sound_device::usb_map(address_map &map)
-{
- map(0x0000, 0x0fff).ram().share("pgmram");
-}
-
-void usb_sound_device::usb_portmap(address_map &map)
-{
- map(0x00, 0xff).rw(FUNC(usb_sound_device::workram_r), FUNC(usb_sound_device::workram_w)).share("workram");
-}
-
-
-//-------------------------------------------------
-// device_add_mconfig - add device configuration
-//-------------------------------------------------
-
-void usb_sound_device::device_add_mconfig(machine_config &config)
-{
- /* CPU for the usb board */
- I8035(config, m_ourcpu, USB_MASTER_CLOCK); /* divide by 15 in CPU */
- m_ourcpu->set_addrmap(AS_PROGRAM, &usb_sound_device::usb_map);
- m_ourcpu->set_addrmap(AS_IO, &usb_sound_device::usb_portmap);
- m_ourcpu->p1_in_cb().set(FUNC(usb_sound_device::p1_r));
- m_ourcpu->p1_out_cb().set(FUNC(usb_sound_device::p1_w));
- m_ourcpu->p2_out_cb().set(FUNC(usb_sound_device::p2_w));
- m_ourcpu->t1_in_cb().set(FUNC(usb_sound_device::t1_r));
-
- TIMER(config, "usb_timer", 0).configure_periodic(
- FUNC(usb_sound_device::increment_t1_clock_timer_cb),
- attotime::from_hz(USB_2MHZ_CLOCK / 256));
-}
-
-
-DEFINE_DEVICE_TYPE(SEGAUSBROM, usb_rom_sound_device, "segausbrom", "Sega Universal Sound Board with ROM")
-
-usb_rom_sound_device::usb_rom_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : usb_sound_device(mconfig, SEGAUSBROM, tag, owner, clock)
-{
-}
-
-void usb_sound_device::usb_map_rom(address_map &map)
-{
- map(0x0000, 0x0fff).rom().region(":usbcpu", 0);
-}
-
-void usb_rom_sound_device::device_add_mconfig(machine_config &config)
-{
- usb_sound_device::device_add_mconfig(config);
-
- /* CPU for the usb board */
- m_ourcpu->set_addrmap(AS_PROGRAM, &usb_rom_sound_device::usb_map_rom);
-}