mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
taito_zm.cpp / zsg2.cpp - more improvements (#3866)
* taito_zm.cpp : Updates Add DSP, Reduce MCFGs, Add device_mixer_interface for sound gain, Add imperfect_features related to DSP, Add notes * taito_zm.cpp : Fix TMS57002 clock * Improve Taito Zoom ZSG-2 sound emulation zsg2.cpp: implement emphasis filter, this is a noise reduction scheme that amplifies higher frequncies to reduce quantization noise. zsg2.cpp: Add sample interpolation and another adjustable lowpass filter. This seems to be roughly what real hardware does... zsg2.cpp: Improve panning registers and identify DSP output gain registers. * zsg2: minor changes [nw] zsg2: Register 0b appears to be status flags [nw] zsg2: Linear ramping probably makes more sense [nw] * zsg2: slight adjustment of emphasis filter [nw] * zsg2: slight adjustment of emphasis filter #2 [nw] * zsg2: more sober ramping algorithm [nw] * tms57002: add instructions 3c/3d, make them behave as NOP as they're undocumented and not understood * tms57002: Add dready callback for superctr (nw) * tms57002: Fixes to make Taito Zoom DSP working tms57002: Add undocumented instruction saom / raom, they set saturation mode for the ALU. tms57002: Implement MACC pipeline. tms57002: Add callbacks for EMPTY and PC0 pins. tms57002: Add a few unimplemented instructions. tms57002: Proper behavior of CMEM UPLOAD mode. tms57002: Fix an issue where program is not properly loaded if PLOAD is set after a program has already been written. * Documentation fix, properly identified registers as ramping control, will implement that soon [nw] * taito_zm: Working DSP emulation Pretty much OST quality now. A pretty decent upgrade from how it was previously, I'd say. * typo [nw] * just adding some quick notes about the WIP [nw] * Fix build [nw] * zsg2: Proper ramping implemenation, add register map, minor cleanups * oops [nw] * taito_zm.cpp / zsg2.cpp - more improvements zsg2.cpp: Attempt to reduce clicks zsg2.cpp: Made the emphasis filter much more simple. I think this matches hardware, as a filter like this could be implemented with very few gates in hardware. Also reset the filter state when the sample position reaches the start address, this fixes raycris song #9 taito_zm.cpp: Adjust volume balance, hopefully fixing psyvarrv. I would need hardware recording for proper verification though tms57002: forgot MACC pipelining for some instructions
This commit is contained in:
parent
c07731b3d4
commit
3492e6ace4
@ -530,7 +530,7 @@ int64_t tms57002_device::macc_to_output_3s(int64_t rounding, uint64_t rmask)
|
||||
|
||||
int64_t tms57002_device::check_macc_overflow_0()
|
||||
{
|
||||
int64_t m = macc;
|
||||
int64_t m = macc_read;
|
||||
uint64_t m1;
|
||||
|
||||
// Overflow detection
|
||||
@ -543,7 +543,7 @@ int64_t tms57002_device::check_macc_overflow_0()
|
||||
|
||||
int64_t tms57002_device::check_macc_overflow_1()
|
||||
{
|
||||
int64_t m = macc;
|
||||
int64_t m = macc_read;
|
||||
uint64_t m1;
|
||||
|
||||
// Overflow detection
|
||||
@ -556,7 +556,7 @@ int64_t tms57002_device::check_macc_overflow_1()
|
||||
|
||||
int64_t tms57002_device::check_macc_overflow_2()
|
||||
{
|
||||
int64_t m = macc;
|
||||
int64_t m = macc_read;
|
||||
uint64_t m1;
|
||||
|
||||
// Overflow detection
|
||||
@ -569,12 +569,12 @@ int64_t tms57002_device::check_macc_overflow_2()
|
||||
|
||||
int64_t tms57002_device::check_macc_overflow_3()
|
||||
{
|
||||
return macc;
|
||||
return macc_read;
|
||||
}
|
||||
|
||||
int64_t tms57002_device::check_macc_overflow_0s()
|
||||
{
|
||||
int64_t m = macc;
|
||||
int64_t m = macc_read;
|
||||
uint64_t m1;
|
||||
|
||||
// Overflow detection
|
||||
@ -591,7 +591,7 @@ int64_t tms57002_device::check_macc_overflow_0s()
|
||||
|
||||
int64_t tms57002_device::check_macc_overflow_1s()
|
||||
{
|
||||
int64_t m = macc;
|
||||
int64_t m = macc_read;
|
||||
uint64_t m1;
|
||||
|
||||
// Overflow detection
|
||||
@ -608,7 +608,7 @@ int64_t tms57002_device::check_macc_overflow_1s()
|
||||
|
||||
int64_t tms57002_device::check_macc_overflow_2s()
|
||||
{
|
||||
int64_t m = macc;
|
||||
int64_t m = macc_read;
|
||||
uint64_t m1;
|
||||
|
||||
// Overflow detection
|
||||
@ -625,7 +625,35 @@ int64_t tms57002_device::check_macc_overflow_2s()
|
||||
|
||||
int64_t tms57002_device::check_macc_overflow_3s()
|
||||
{
|
||||
return macc;
|
||||
return macc_read;
|
||||
}
|
||||
|
||||
uint32_t tms57002_device::get_cmem(uint8_t addr)
|
||||
{
|
||||
if(sa == addr && update_counter_head != update_counter_tail)
|
||||
sti |= S_UPDATE;
|
||||
|
||||
if(sti & S_UPDATE)
|
||||
{
|
||||
cmem[addr] = update[update_counter_tail];
|
||||
update_counter_tail = (update_counter_tail + 1) & 0x0f;
|
||||
update_empty();
|
||||
|
||||
if(update_counter_head == update_counter_tail)
|
||||
sti &= ~S_UPDATE;
|
||||
|
||||
return cmem[addr]; // The value of crm is ignored during an update.
|
||||
}
|
||||
else
|
||||
{
|
||||
int crm = (st1 & ST1_CRM) >> ST1_CRM_SHIFT;
|
||||
uint32_t cvar = cmem[addr];
|
||||
if(crm == 1)
|
||||
return (cvar & 0xffff0000);
|
||||
else if(crm == 2)
|
||||
return (cvar << 16);
|
||||
return cvar;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t tms57002_device::get_cmem(uint8_t addr)
|
||||
|
@ -24,14 +24,14 @@
|
||||
+00c : xxxxxxxx xxxxxxxx : End address
|
||||
+00e : xxxxxxxx -------- : DSP ch 2 (Left) output gain
|
||||
: -------- xxxxxxxx : Loop address (high)
|
||||
+010 : xxxxxxxx xxxxxxxx : Filter time constant (latch)
|
||||
+012 : -------- -------- : Unknown register (usually cleared)
|
||||
+014 : xxxxxxxx xxxxxxxx : Volume (latch)
|
||||
+016 : --x----- -------- : Key on status flag (only read)
|
||||
+018 : xxxxxxxx xxxxxxxx : Filter time constant (Ramping target)
|
||||
+010 : xxxxxxxx xxxxxxxx : Initial filter time constant
|
||||
+012 : xxxxxxxx xxxxxxxx : Current filter time constant
|
||||
+014 : xxxxxxxx xxxxxxxx : Initial volume
|
||||
+016 : xxxxxxxx xxxxxxxx : Current volume
|
||||
+018 : xxxxxxxx xxxxxxxx : Target filter time constant
|
||||
+01a : xxxxxxxx -------- : DSP ch 1 (chorus) output gain
|
||||
: -------- xxxxxxxx : Filter ramping speed
|
||||
+01c : xxxxxxxx xxxxxxxx : Volume (target)
|
||||
+01c : xxxxxxxx xxxxxxxx : Target volume
|
||||
+01e : xxxxxxxx -------- : DSP ch 0 (reverb) output gain
|
||||
: -------- xxxxxxxx : Filter ramping speed
|
||||
600-604 : Key on flags (each bit corresponds to a channel)
|
||||
@ -97,8 +97,11 @@ TODO:
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
|
||||
#define EMPHASIS_CUTOFF_BASE 0x800
|
||||
#define EMPHASIS_OUTPUT_SHIFT 15
|
||||
//#define EMPHASIS_CUTOFF_BASE 0x0800
|
||||
//#define EMPHASIS_INITIAL_BIAS 0x00400000
|
||||
#define EMPHASIS_INITIAL_BIAS 0
|
||||
#define EMPHASIS_OUTPUT_SHIFT (16-11)
|
||||
#define SAMPLE_OUTPUT_SHIFT 12
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(ZSG2, zsg2_device, "zsg2", "ZOOM ZSG-2")
|
||||
@ -138,13 +141,12 @@ void zsg2_device::device_start()
|
||||
save_item(NAME(m_read_address));
|
||||
|
||||
// Generate the output gain table. Assuming -1dB per step for now.
|
||||
for (int i = 0, history=0; i < 32; i++)
|
||||
for (int i = 1; i < 32; i++)
|
||||
{
|
||||
double val = pow(10, -(31 - i) / 20.) * 65535.;
|
||||
gain_tab[i] = val;
|
||||
gain_tab_frac[i] = val-history;
|
||||
history = val;
|
||||
m_gain_tab[i] = val;
|
||||
}
|
||||
m_gain_tab[0] = 0;
|
||||
|
||||
for (int ch = 0; ch < 48; ch++)
|
||||
{
|
||||
@ -175,7 +177,7 @@ void zsg2_device::device_start()
|
||||
|
||||
save_item(NAME(m_chan[ch].samples), ch);
|
||||
}
|
||||
|
||||
|
||||
save_item(NAME(m_sample_count));
|
||||
}
|
||||
|
||||
@ -204,11 +206,11 @@ void zsg2_device::device_reset()
|
||||
FILE* f;
|
||||
|
||||
f = fopen("zoom_samples.bin","wb");
|
||||
fwrite(m_mem_copy,1,m_mem_blocks*4,f);
|
||||
fwrite(m_mem_copy.get(),1,m_mem_blocks*4,f);
|
||||
fclose(f);
|
||||
|
||||
f = fopen("zoom_samples.raw","wb");
|
||||
fwrite(m_full_samples,2,m_mem_blocks*4,f);
|
||||
fwrite(m_full_samples.get(),2,m_mem_blocks*4,f);
|
||||
fclose(f);
|
||||
#endif
|
||||
}
|
||||
@ -267,10 +269,8 @@ void zsg2_device::filter_samples(zchan *ch)
|
||||
{
|
||||
ch->samples[i+1] = raw_samples[i];
|
||||
|
||||
// not sure if the filter works exactly this way, however I am pleased
|
||||
// with the output for now.
|
||||
ch->emphasis_filter_state += (raw_samples[i]-(ch->emphasis_filter_state>>16)) * EMPHASIS_CUTOFF_BASE;
|
||||
ch->samples[i+1] = (ch->emphasis_filter_state) >> EMPHASIS_OUTPUT_SHIFT;
|
||||
ch->emphasis_filter_state += raw_samples[i]-(ch->emphasis_filter_state>>EMPHASIS_OUTPUT_SHIFT);
|
||||
ch->samples[i+1] = ch->emphasis_filter_state >> EMPHASIS_OUTPUT_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,20 +285,15 @@ void zsg2_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
|
||||
{
|
||||
int32_t mix[4] = {};
|
||||
|
||||
int ch = 0;
|
||||
|
||||
// loop over all channels
|
||||
for (auto & elem : m_chan)
|
||||
//auto & elem = m_chan[0];
|
||||
{
|
||||
ch++;
|
||||
if (!(elem.status & STATUS_ACTIVE))
|
||||
if(~elem.status & STATUS_ACTIVE)
|
||||
continue;
|
||||
|
||||
elem.step_ptr += elem.step;
|
||||
if (elem.step_ptr & 0x10000)
|
||||
if (elem.step_ptr & 0xffff0000)
|
||||
{
|
||||
elem.step_ptr &= 0xffff;
|
||||
if (++elem.cur_pos >= elem.end_pos)
|
||||
{
|
||||
// loop sample
|
||||
@ -306,26 +301,30 @@ void zsg2_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
|
||||
if ((elem.cur_pos + 1) >= elem.end_pos)
|
||||
{
|
||||
// end of sample
|
||||
elem.vol = 0; //this should help the channel allocation just a bit
|
||||
elem.status &= ~STATUS_ACTIVE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(elem.cur_pos == elem.start_pos)
|
||||
elem.emphasis_filter_state = EMPHASIS_INITIAL_BIAS;
|
||||
}
|
||||
elem.step_ptr &= 0xffff;
|
||||
filter_samples(&elem);
|
||||
}
|
||||
|
||||
uint8_t sample_pos = elem.step_ptr >> 14 & 3;
|
||||
int32_t sample; // = elem.samples[sample_pos];
|
||||
int32_t sample = elem.samples[sample_pos];
|
||||
|
||||
// linear interpolation (hardware certainly does something similar)
|
||||
sample = elem.samples[sample_pos];
|
||||
sample += ((uint16_t)(elem.step_ptr<<2&0xffff) * (int16_t)(elem.samples[sample_pos+1] - sample))>>16;
|
||||
|
||||
sample = (sample * elem.vol) >> 16;
|
||||
|
||||
// another filter...
|
||||
elem.output_filter_state += (sample - (elem.output_filter_state>>16)) * elem.output_cutoff;
|
||||
sample = elem.output_filter_state >> 16;
|
||||
|
||||
sample = (sample * elem.vol)>>16;
|
||||
|
||||
for(int output=0; output<4; output++)
|
||||
{
|
||||
int output_gain = elem.output_gain[output] & 0x1f; // left / right
|
||||
@ -334,7 +333,7 @@ void zsg2_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
|
||||
if (elem.output_gain[output] & 0x80) // perhaps ?
|
||||
output_sample = -output_sample;
|
||||
|
||||
mix[output] += (output_sample * gain_tab[output_gain&0x1f]) >> 13;
|
||||
mix[output] += (output_sample * m_gain_tab[output_gain&0x1f]) >> SAMPLE_OUTPUT_SHIFT;
|
||||
}
|
||||
|
||||
// Apply ramping every other update
|
||||
@ -346,8 +345,6 @@ void zsg2_device::sound_stream_update(sound_stream &stream, stream_sample_t **in
|
||||
}
|
||||
}
|
||||
|
||||
ch = 0;
|
||||
|
||||
for(int output=0; output<4; output++)
|
||||
outputs[output][i] = mix[output];
|
||||
|
||||
@ -379,7 +376,9 @@ void zsg2_device::chan_w(int ch, int reg, uint16_t data)
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
// unknown, always 0x0400
|
||||
// unknown, always 0x0400. is this a flag?
|
||||
m_chan[ch].status &= 0x8000;
|
||||
m_chan[ch].status |= data & 0x7fff;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
@ -412,7 +411,8 @@ void zsg2_device::chan_w(int ch, int reg, uint16_t data)
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
// no function? always 0
|
||||
// writes 0 at key on
|
||||
m_chan[ch].output_cutoff = data;
|
||||
break;
|
||||
|
||||
case 0xa:
|
||||
@ -421,8 +421,8 @@ void zsg2_device::chan_w(int ch, int reg, uint16_t data)
|
||||
break;
|
||||
|
||||
case 0xb:
|
||||
// always writes 0
|
||||
// this register is read-only
|
||||
// writes 0 at key on
|
||||
m_chan[ch].vol = data;
|
||||
break;
|
||||
|
||||
case 0xc:
|
||||
@ -460,8 +460,16 @@ uint16_t zsg2_device::chan_r(int ch, int reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0xb: // Only later games (taitogn) read this register...
|
||||
case 0x3:
|
||||
// no games read from this.
|
||||
return m_chan[ch].status;
|
||||
case 0x9:
|
||||
// pretty certain, though no games actually read from this.
|
||||
return m_chan[ch].output_cutoff;
|
||||
case 0xb: // Only later games (taitogn) read this register...
|
||||
// GNet games use some of the flags to decide which channels to kill when
|
||||
// all the channels are busy. (take raycris song #23 as an example)
|
||||
return m_chan[ch].vol;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -479,14 +487,12 @@ int16_t zsg2_device::get_ramp(uint8_t val)
|
||||
{
|
||||
int16_t frac = val<<12; // sign extend
|
||||
frac = ((frac>>12) ^ 8) << (val >> 4);
|
||||
|
||||
return (frac >> 4);
|
||||
}
|
||||
|
||||
inline uint16_t zsg2_device::ramp(uint16_t current, uint16_t target, int16_t delta)
|
||||
{
|
||||
int32_t rampval = current + delta;
|
||||
|
||||
if(delta < 0 && rampval < target)
|
||||
rampval = target;
|
||||
else if(delta >= 0 && rampval > target)
|
||||
@ -511,12 +517,12 @@ void zsg2_device::control_w(int reg, uint16_t data)
|
||||
{
|
||||
int ch = base | i;
|
||||
m_chan[ch].status |= STATUS_ACTIVE;
|
||||
m_chan[ch].cur_pos = m_chan[ch].start_pos;
|
||||
m_chan[ch].step_ptr = 0;
|
||||
m_chan[ch].emphasis_filter_state = 0;
|
||||
m_chan[ch].vol = m_chan[ch].vol_initial;
|
||||
m_chan[ch].cur_pos = m_chan[ch].start_pos - 1;
|
||||
m_chan[ch].step_ptr = 0x10000;
|
||||
// Ignoring the "initial volume" for now because it causes lots of clicking
|
||||
m_chan[ch].vol = 0; // m_chan[ch].vol_initial;
|
||||
m_chan[ch].vol_delta = 0x0400; // register 06 ?
|
||||
m_chan[ch].output_cutoff = m_chan[ch].output_cutoff_initial;
|
||||
filter_samples(&m_chan[ch]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -531,6 +537,7 @@ void zsg2_device::control_w(int reg, uint16_t data)
|
||||
if (data & (1 << i))
|
||||
{
|
||||
int ch = base | i;
|
||||
m_chan[ch].vol = 0;
|
||||
m_chan[ch].status &= ~STATUS_ACTIVE;
|
||||
}
|
||||
}
|
||||
@ -558,6 +565,8 @@ void zsg2_device::control_w(int reg, uint16_t data)
|
||||
break;
|
||||
|
||||
default:
|
||||
if(reg < 0x20)
|
||||
m_reg[reg] = data;
|
||||
logerror("ZSG2 control %02X = %04X\n", reg, data & 0xffff);
|
||||
break;
|
||||
}
|
||||
@ -580,6 +589,8 @@ uint16_t zsg2_device::control_r(int reg)
|
||||
return read_memory(m_read_address) >> 16;
|
||||
|
||||
default:
|
||||
if(reg < 0x20)
|
||||
return m_reg[reg];
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -41,13 +41,12 @@ protected:
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
||||
|
||||
private:
|
||||
const uint16_t STATUS_ACTIVE = 0x2000;
|
||||
const uint16_t STATUS_ACTIVE = 0x8000;
|
||||
|
||||
// 16 registers per channel, 48 channels
|
||||
struct zchan
|
||||
{
|
||||
uint16_t v[16];
|
||||
|
||||
uint16_t status;
|
||||
uint32_t cur_pos;
|
||||
uint32_t step_ptr;
|
||||
@ -68,6 +67,7 @@ private:
|
||||
int16_t output_cutoff_delta;
|
||||
|
||||
int32_t emphasis_filter_state;
|
||||
|
||||
int32_t output_filter_state;
|
||||
|
||||
// Attenuation for output channels
|
||||
@ -76,8 +76,8 @@ private:
|
||||
int16_t samples[5]; // +1 history
|
||||
};
|
||||
|
||||
uint16_t gain_tab[256];
|
||||
uint16_t gain_tab_frac[256];
|
||||
uint16_t m_gain_tab[256];
|
||||
uint16_t m_reg[32];
|
||||
|
||||
zchan m_chan[48];
|
||||
uint32_t m_sample_count;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Olivier Galibert, hap
|
||||
// copyright-holders:Olivier Galibert, hap, superctr, cam900
|
||||
/***************************************************************************
|
||||
|
||||
Taito Zoom ZSG-2 sound board
|
||||
@ -18,16 +18,23 @@ Texas Instruments TMS57002DPHA DSP (QFP80)
|
||||
* 1.5625MHz pin 75 and 2 [25/16] (BCKI) (BCKO)
|
||||
|
||||
Newer games have a Panasonic MN1020819DA,
|
||||
and a Zoom Corp. ZFX-2 DSP instead of the TMS57002.
|
||||
|
||||
and a Zoom Corp. ZFX-2 DSP instead of the TMS57002 (Functionally identical).
|
||||
|
||||
TODO:
|
||||
<<<<<<< HEAD
|
||||
- ZSG-2 sound chip emulation might not be perfect, see zsg2.cpp
|
||||
|
||||
- check DSP behavior. The DSP is programmed to expect 16-bit samples, but
|
||||
the range of the sample values seem really low. Normally the TMS57002 is
|
||||
supposed to left-shift 16-bit samples, but is this the case here?
|
||||
=======
|
||||
- Raycrisis song 9 gets cut off due to clipping. Possible DSP emulation bug,
|
||||
or just have to change the volumes. in the sound test, it will start to cut
|
||||
at about 55%. and the timbre doesn't sound right anyway.
|
||||
|
||||
- check DSP behavior
|
||||
- Implement the ramping control registers in zsg2.cpp
|
||||
>>>>>>> upstream/master
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -209,8 +216,8 @@ MACHINE_CONFIG_START(taito_zoom_device::device_add_mconfig)
|
||||
m_tms57002->empty_callback().set_inputline(m_soundcpu, MN10200_IRQ1).invert();
|
||||
|
||||
m_tms57002->set_addrmap(AS_DATA, &taito_zoom_device::tms57002_map);
|
||||
m_tms57002->add_route(2, *this, 1.0, AUTO_ALLOC_INPUT, 0);
|
||||
m_tms57002->add_route(3, *this, 1.0, AUTO_ALLOC_INPUT, 1);
|
||||
m_tms57002->add_route(2, *this, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_tms57002->add_route(3, *this, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
#else // Unsupported opcode issue
|
||||
m_tms57002->set_disable();
|
||||
#endif
|
||||
@ -219,11 +226,11 @@ MACHINE_CONFIG_START(taito_zoom_device::device_add_mconfig)
|
||||
#ifdef USE_DSP
|
||||
m_zsg2->add_route(0, *m_tms57002, 0.5, 0); // reverb effect
|
||||
m_zsg2->add_route(1, *m_tms57002, 0.5, 1); // chorus effect
|
||||
m_zsg2->add_route(2, *m_tms57002, 0.5, 2); // left direct
|
||||
m_zsg2->add_route(3, *m_tms57002, 0.5, 3); // right direct
|
||||
m_zsg2->add_route(2, *m_tms57002, 1.0, 2); // left direct
|
||||
m_zsg2->add_route(3, *m_tms57002, 1.0, 3); // right direct
|
||||
#else
|
||||
m_zsg2->add_route(2, *this, 1.0, AUTO_ALLOC_INPUT, 0);
|
||||
m_zsg2->add_route(3, *this, 1.0, AUTO_ALLOC_INPUT, 1);
|
||||
m_zsg2->add_route(2, *this, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_zsg2->add_route(3, *this, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
#endif
|
||||
|
||||
MACHINE_CONFIG_END
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Olivier Galibert, hap
|
||||
// copyright-holders:Olivier Galibert, hap, superctr, cam900
|
||||
/***************************************************************************
|
||||
|
||||
Taito Zoom ZSG-2 sound board
|
||||
@ -14,7 +14,7 @@
|
||||
#include "cpu/tms57002/tms57002.h"
|
||||
#include "sound/zsg2.h"
|
||||
|
||||
#define USE_DSP // Uncomment when DSP emulation is working
|
||||
#define USE_DSP // comment out this to disable DSP emulation
|
||||
|
||||
class taito_zoom_device : public device_t, public device_mixer_interface
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user