vgmplay: start all clocks at zero and reset all sound chips on a song change [smf]

This commit is contained in:
smf- 2018-07-27 22:01:32 +01:00
parent 5460bc0d3d
commit 20b5f5d0e6
14 changed files with 299 additions and 259 deletions

View File

@ -40,7 +40,7 @@ void ym2203_device::device_timer(emu_timer &timer, device_timer_id id, int param
void ym2203_device::timer_handler(int c, int count, int clock)
{
if( count == 0 )
if( count == 0 || clock == 0)
{ /* Reset FM Timer */
m_timer[c]->enable(false);
}

View File

@ -11,9 +11,6 @@
- Control Write B
- Data Write B
TODO:
- fix set_unscaled_clock() changes (currently done only by vgmplay driver)
***************************************************************************/
#include "emu.h"
@ -52,7 +49,7 @@ void ym2608_device::device_timer(emu_timer &timer, device_timer_id id, int param
void ym2608_device::timer_handler(int c,int count,int clock)
{
if( count == 0 )
if( count == 0 || clock == 0 )
{ /* Reset FM Timer */
m_timer[c]->enable(false);
}
@ -110,6 +107,16 @@ void ym2608_device::device_start()
assert_always(m_chip != nullptr, "Error creating YM2608 chip");
}
//-------------------------------------------------
// device_clock_changed
//-------------------------------------------------
void ym2608_device::device_clock_changed()
{
m_stream->set_sample_rate(clock() / 72);
ym2608_clock_changed(m_chip, clock(), clock() / 72);
}
//-------------------------------------------------
// device_stop - device-specific stop
//-------------------------------------------------

View File

@ -32,6 +32,7 @@ protected:
// device-level overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_start() override;
virtual void device_clock_changed() override;
virtual void device_post_load() override;
virtual void device_stop() override;
virtual void device_reset() override;

View File

@ -277,14 +277,14 @@ void c6280_device::calculate_clocks()
/* Make waveform frequency table */
for (int i = 0; i < 4096; i += 1)
{
double step = ((clock() / rate) * 4096) / (i + 1);
double step = (16 * 4096) / (i + 1);
m_wave_freq_tab[(1 + i) & 0xFFF] = (uint32_t)step;
}
/* Make noise frequency table */
for (int i = 0; i < 32; i += 1)
{
double step = ((clock() / rate) * 32) / (i+1);
double step = (16 * 32) / (i+1);
m_noise_freq_tab[i] = (uint32_t)step;
}

View File

@ -3011,6 +3011,14 @@ void * ym2608_init(device_t *device, int clock, int rate, void *pcmrom,int pcmsi
return F2608;
}
void ym2608_clock_changed(void *chip, int clock, int rate)
{
ym2608_state *F2608 = (ym2608_state *)chip;
F2608->OPN.ST.clock = clock;
F2608->OPN.ST.rate = rate;
}
/* shut down emulator */
void ym2608_shutdown(void *chip)
{

View File

@ -136,6 +136,7 @@ void ym2203_postload(void *chip);
void * ym2608_init(device_t *device, int baseclock, int rate,
void *pcmroma,int pcmsizea,
FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg);
void ym2608_clock_changed(void *chip, int clock, int rate);
void ym2608_shutdown(void *chip);
void ym2608_reset_chip(void *chip);
void ym2608_update_one(void *chip, FMSAMPLE **buffer, int length);

View File

@ -1631,7 +1631,7 @@ void FM_OPL::initialize()
/*logerror("freqbase=%f\n", freqbase);*/
/* Timer base time */
TimerBase = attotime::from_hz(clock) * 72;
TimerBase = clock ? attotime::from_hz(clock) * 72 : attotime::zero;
/* make fnumber -> increment counter table */
for( i=0 ; i < 1024 ; i++ )

View File

@ -169,6 +169,16 @@ void gameboy_sound_device::device_start()
}
//-------------------------------------------------
// device_clock_changed
//-------------------------------------------------
void gameboy_sound_device::device_clock_changed()
{
m_timer->adjust(clocks_to_attotime(FRAME_CYCLES / 128), 0, clocks_to_attotime(FRAME_CYCLES / 128));
}
//-------------------------------------------------
// device_reset
//-------------------------------------------------

View File

@ -21,6 +21,7 @@ protected:
// device-level overrides
virtual void device_start() override;
virtual void device_clock_changed() override;
virtual void device_reset() override;
// sound stream update overrides

View File

@ -1615,6 +1615,14 @@ void ym2413_device::device_start()
}
}
//-------------------------------------------------
// device_clock_changed
//-------------------------------------------------
void ym2413_device::device_clock_changed()
{
m_stream->set_sample_rate(clock() / 72);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------

View File

@ -19,6 +19,7 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_clock_changed() override;
virtual void device_reset() override;
// sound stream update overrides

View File

@ -452,7 +452,12 @@ void device_scheduler::timeslice()
{
// only process if this CPU is executing or truly halted (not yielding)
// and if our target is later than the CPU's current time (coarse check)
if (EXPECTED((exec->m_suspend == 0 || exec->m_eatcycles) && target.seconds() >= exec->m_localtime.seconds()))
if (exec->m_suspend != 0)
{
if (exec->m_eatcycles)
exec->m_localtime = target;
}
else if (target.seconds() >= exec->m_localtime.seconds())
{
// compute how many attoseconds to execute this CPU
attoseconds_t delta = target.attoseconds() - exec->m_localtime.attoseconds();
@ -467,33 +472,29 @@ void device_scheduler::timeslice()
int ran = exec->m_cycles_running = divu_64x32(u64(delta) >> exec->m_divshift, exec->m_divisor);
LOG((" cpu '%s': %d (%d cycles)\n", exec->device().tag(), delta, exec->m_cycles_running));
// if we're not suspended, actually execute
if (exec->m_suspend == 0)
g_profiler.start(exec->m_profiler);
// note that this global variable cycles_stolen can be modified
// via the call to cpu_execute
exec->m_cycles_stolen = 0;
m_executing_device = exec;
*exec->m_icountptr = exec->m_cycles_running;
if (!call_debugger)
exec->run();
else
{
g_profiler.start(exec->m_profiler);
// note that this global variable cycles_stolen can be modified
// via the call to cpu_execute
exec->m_cycles_stolen = 0;
m_executing_device = exec;
*exec->m_icountptr = exec->m_cycles_running;
if (!call_debugger)
exec->run();
else
{
exec->debugger_start_cpu_hook(target);
exec->run();
exec->debugger_stop_cpu_hook();
}
// adjust for any cycles we took back
assert(ran >= *exec->m_icountptr);
ran -= *exec->m_icountptr;
assert(ran >= exec->m_cycles_stolen);
ran -= exec->m_cycles_stolen;
g_profiler.stop();
exec->debugger_start_cpu_hook(target);
exec->run();
exec->debugger_stop_cpu_hook();
}
// adjust for any cycles we took back
assert(ran >= *exec->m_icountptr);
ran -= *exec->m_icountptr;
assert(ran >= exec->m_cycles_stolen);
ran -= exec->m_cycles_stolen;
g_profiler.stop();
// account for these cycles
exec->m_totalcycles += ran;

View File

@ -264,6 +264,9 @@ void sound_stream::set_input(int index, sound_stream *input_stream, int output_i
void sound_stream::update()
{
if (!m_attoseconds_per_sample)
return;
// determine the number of samples since the start of this second
attotime time = m_device.machine().time();
s32 update_sampindex = s32(time.attoseconds() / m_attoseconds_per_sample);
@ -439,8 +442,17 @@ void sound_stream::apply_sample_rate_changes()
recompute_sample_rate_data();
// reset our sample indexes to the current time
m_output_sampindex = s64(m_output_sampindex) * s64(m_sample_rate) / old_rate;
m_output_update_sampindex = s64(m_output_update_sampindex) * s64(m_sample_rate) / old_rate;
if (old_rate)
{
m_output_sampindex = s64(m_output_sampindex) * s64(m_sample_rate) / old_rate;
m_output_update_sampindex = s64(m_output_update_sampindex) * s64(m_sample_rate) / old_rate;
}
else
{
m_output_sampindex = m_device.machine().sound().last_update().attoseconds() / m_attoseconds_per_sample;
m_output_update_sampindex = m_output_sampindex;
}
m_output_base_sampindex = m_output_sampindex - m_max_samples_per_update;
// clear out the buffer
@ -471,15 +483,22 @@ void sound_stream::recompute_sample_rate_data()
throw emu_fatalerror("Incompatible sample rates as input of a synchronous stream: %d and %d\n", m_sample_rate, input.m_source->m_stream->m_sample_rate);
}
}
if (!m_sample_rate)
m_sample_rate = 1000;
}
// recompute the timing parameters
attoseconds_t update_attoseconds = m_device.machine().sound().update_attoseconds();
m_attoseconds_per_sample = ATTOSECONDS_PER_SECOND / m_sample_rate;
m_max_samples_per_update = (update_attoseconds + m_attoseconds_per_sample - 1) / m_attoseconds_per_sample;
if (m_sample_rate)
{
m_attoseconds_per_sample = ATTOSECONDS_PER_SECOND / m_sample_rate;
m_max_samples_per_update = (update_attoseconds + m_attoseconds_per_sample - 1) / m_attoseconds_per_sample;
}
else
{
m_attoseconds_per_sample = 0;
m_max_samples_per_update = 0;
}
// update resample and output buffer sizes
allocate_resample_buffers();
@ -490,7 +509,7 @@ void sound_stream::recompute_sample_rate_data()
{
// if we have a source, see if its sample rate changed
if (input.m_source != nullptr)
if (input.m_source != nullptr && input.m_source->m_stream->m_sample_rate)
{
// okay, we have a new sample rate; recompute the latency to be the maximum
// sample period between us and our input
@ -511,6 +530,10 @@ void sound_stream::recompute_sample_rate_data()
input.m_latency_attoseconds = std::max(input.m_latency_attoseconds, latency);
assert(input.m_latency_attoseconds < update_attoseconds);
}
else
{
input.m_latency_attoseconds = 0;
}
}
// If synchronous, prime the timer
@ -653,7 +676,7 @@ stream_sample_t *sound_stream::generate_resampled_data(stream_input &input, u32
{
// if we don't have an output to pull data from, generate silence
stream_sample_t *dest = &input.m_resample[0];
if (input.m_source == nullptr)
if (input.m_source == nullptr || input.m_source->m_buffer.size() == 0)
{
memset(dest, 0, numsamples * sizeof(*dest));
return &input.m_resample[0];

View File

@ -720,11 +720,11 @@ void vgmplay_device::execute_run()
pulse_act_led(LED_AY8910);
uint8_t reg = m_file->read_byte(m_pc+1);
if(reg & 0x80) {
m_io->write_byte(A_AY8910A+1, reg & 0x7f);
m_io->write_byte(A_AY8910A+0, m_file->read_byte(m_pc+2));
} else {
m_io->write_byte(A_AY8910B+1, reg & 0x7f);
m_io->write_byte(A_AY8910B+0, m_file->read_byte(m_pc+2));
} else {
m_io->write_byte(A_AY8910A+1, reg & 0x7f);
m_io->write_byte(A_AY8910A+0, m_file->read_byte(m_pc+2));
}
m_pc += 3;
break;
@ -792,9 +792,9 @@ void vgmplay_device::execute_run()
pulse_act_led(LED_POKEY);
uint8_t offset = m_file->read_byte(m_pc+1);
if (offset & 0x80)
m_io->write_byte(A_POKEYA + (offset & 0x7f), m_file->read_byte(m_pc+2));
else
m_io->write_byte(A_POKEYB + (offset & 0x7f), m_file->read_byte(m_pc+2));
else
m_io->write_byte(A_POKEYA + (offset & 0x7f), m_file->read_byte(m_pc+2));
m_pc += 3;
break;
}
@ -1419,12 +1419,23 @@ uint8_t vgmplay_state::r8(int off) const
return 0;
}
static const ay8910_device::psg_type_t vgm_ay8910_type(uint8_t vgm_type)
{
return (vgm_type & 0x10) ? ay8910_device::PSG_TYPE_YM : ay8910_device::PSG_TYPE_AY;
}
static const uint8_t vgm_ay8910_flags(uint8_t vgm_flags)
{
uint8_t flags = 0;
if (vgm_flags & 1) flags |= AY8910_LEGACY_OUTPUT;
if (vgm_flags & 2) flags |= AY8910_SINGLE_OUTPUT;
if (vgm_flags & 4) flags |= AY8910_DISCRETE_OUTPUT;
return flags;
}
QUICKLOAD_LOAD_MEMBER(vgmplay_state, load_file)
{
// Disable executing devices if not required
m_pokey[0]->set_unscaled_clock(0);
m_pokey[1]->set_unscaled_clock(0);
m_qsound->set_unscaled_clock(0);
m_vgmplay->stop();
m_file_data.resize(quickload_size);
@ -1495,188 +1506,157 @@ QUICKLOAD_LOAD_MEMBER(vgmplay_state, load_file)
if (version >= 0x150 && r32(0x34))
data_start = r32(0x34) + 0x34;
if (data_start < header_size)
logerror("Warning: data starts within header\n");
// Parse clocks
if(r32(0x0c))
m_sn76496->set_unscaled_clock(r32(0x0c));
if(r32(0x10))
m_ym2413->set_unscaled_clock(r32(0x10));
if(version >= 0x110 && r32(0x2c))
m_ym2612->set_unscaled_clock(r32(0x2c));
if(version >= 0x110 && r32(0x30))
m_ym2151->set_unscaled_clock(r32(0x30));
m_sn76496->set_unscaled_clock(r32(0x0c) & ~0xc0000000);
if (r32(0x0c) & 0xc0000000)
logerror("Warning: file requests an unsupported %s\n", r32(0x0c) & 0x80000000 ? "Y6W28" : "2nd SN76496");
if(version >= 0x151 && r32(0x38))
m_segapcm->set_unscaled_clock(r32(0x38));
m_ym2413->set_unscaled_clock(r32(0x10) & ~0x40000000);
if (r32(0x10) & 0x40000000)
logerror("Warning: file requests an unsupported 2nd YM2413\n");
if(version >= 0x151 && r32(0x3c))
m_segapcm->set_bank(r32(0x3c));
m_ym2612->set_unscaled_clock((version >= 0x110 ? r32(0x2c) : r32(0x10)) & ~0x40000000);
if (version >= 0x110 && (r32(0x2c) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd YM2612\n");
if (data_start > 0x40)
{
if(version >= 0x151 && r32(0x40))
m_rf5c68->set_unscaled_clock(r32(0x40));
if(version >= 0x151 && r32(0x44)) {
uint32_t clock = r32(0x44);
m_ym2203[0]->set_unscaled_clock(clock & ~0x40000000);
if (clock & 0x40000000)
{
clock &= ~0x40000000;
m_ym2203[1]->set_unscaled_clock(clock);
}
}
if(version >= 0x151 && r32(0x48))
m_ym2608->set_unscaled_clock(r32(0x48));
if(version >= 0x151 && r32(0x4c))
logerror("Warning: file requests an unsupported %s\n", r32(0x4c) & 0x80000000 ? "YM2610B" : "YM2610");
if(version >= 0x151 && r32(0x50)) {
m_ym3812->set_unscaled_clock(r32(0x50));
}
if(version >= 0x151 && r32(0x54)) {
m_ym3526->set_unscaled_clock(r32(0x54));
}
if(version >= 0x151 && r32(0x58))
logerror("Warning: file requests an unsupported Y8950\n");
if(version >= 0x151 && r32(0x5c))
logerror("Warning: file requests an unsupported YMF262\n");
if(version >= 0x151 && r32(0x60))
logerror("Warning: file requests an unsupported YMF278B\n");
if(version >= 0x151 && r32(0x64)) {
m_ymf271->set_unscaled_clock(r32(0x64));
}
if(version >= 0x151 && r32(0x68)) {
m_ymz280b->set_unscaled_clock(r32(0x68));
}
if(version >= 0x151 && r32(0x6c))
m_rf5c164->set_unscaled_clock(r32(0x6c));
if(version >= 0x151 && r32(0x70))
logerror("Warning: file requests an unsupported PWM\n");
if(version >= 0x151 && r32(0x74)) {
uint32_t clock = r32(0x74);
m_ay8910[0]->set_unscaled_clock(clock & ~0x40000000);
if (clock & 0x40000000) {
clock &= ~0x40000000;
m_ay8910[1]->set_unscaled_clock(clock);
}
}
if(version >= 0x151 && r8(0x78)) {
uint8_t type = r8(0x78);
if (type & 0x10)
{
m_ay8910[0]->set_psg_type(ay8910_device::PSG_TYPE_YM);
m_ay8910[1]->set_psg_type(ay8910_device::PSG_TYPE_YM);
}
}
if(version >= 0x151 && r8(0x79)) {
uint8_t flags = r8(0x79);
uint8_t to_set = 0;
if (flags & 1)
to_set |= AY8910_LEGACY_OUTPUT;
if (flags & 2)
to_set |= AY8910_SINGLE_OUTPUT;
if (flags & 4)
to_set |= AY8910_DISCRETE_OUTPUT;
m_ay8910[0]->set_flags(to_set);
m_ay8910[1]->set_flags(to_set);
}
if(version >= 0x151 && r8(0x7a)) {
uint8_t flags = r8(0x7a);
uint8_t to_set = 0;
if (flags & 1)
to_set |= AY8910_LEGACY_OUTPUT;
if (flags & 2)
to_set |= AY8910_SINGLE_OUTPUT;
if (flags & 4)
to_set |= AY8910_DISCRETE_OUTPUT;
m_ym2203[0]->set_flags(to_set);
m_ym2203[1]->set_flags(to_set);
}
}
m_ym2151->set_unscaled_clock((version >= 0x110 ? r32(0x30) : r32(0x10)) & ~0x40000000);
if (version >= 0x110 && (r32(0x30) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd YM2151\n");
if (data_start > 0x80)
{
if(version >= 0x161 && r32(0x80)) {
m_dmg->set_unscaled_clock(r32(0x80));
}
if(version >= 0x161 && r32(0x84)) {
m_nescpu->set_unscaled_clock(r32(0x84));
m_nescpu->m_apu->set_unscaled_clock(r32(0x84));
}
if(version >= 0x161 && r32(0x88)) {
uint32_t clock = r32(0x88);
m_multipcm[0]->set_unscaled_clock(clock & ~0x40000000);
if (clock & 0x40000000) {
clock &= ~0x40000000;
m_multipcm[1]->set_unscaled_clock(clock);
}
}
if(version >= 0x161 && r8(0x95)) {
m_k054539[0]->init_flags(r8(0x95));
m_k054539[1]->init_flags(r8(0x95));
}
if(version >= 0x161 && r32(0x98)) {
m_okim6295_clock[0] = r32(0x98);
m_okim6295_pin7[0] = 0;
if (m_okim6295_clock[0] & 0x80000000) {
m_okim6295_clock[0] &= ~0x80000000;
m_okim6295_pin7[0] = 1;
}
m_okim6295[0]->config_pin7(m_okim6295_pin7[0] ? okim6295_device::PIN7_HIGH : okim6295_device::PIN7_LOW); // FIXME: no guarantee this device hasn't started yet - may be better to wait for it to start then use set_pin7
m_okim6295[0]->set_unscaled_clock(m_okim6295_clock[0] & ~0xc0000000);
if (m_okim6295_clock[0] & 0x40000000) {
m_okim6295_clock[0] &= ~0x40000000;
m_okim6295_clock[1] = m_okim6295_clock[0];
m_okim6295_pin7[1] = m_okim6295_pin7[0];
m_okim6295[1]->config_pin7(m_okim6295_pin7[1] ? okim6295_device::PIN7_HIGH : okim6295_device::PIN7_LOW); // FIXME: no guarantee this device hasn't started yet - may be better to wait for it to start then use set_pin7
m_okim6295[1]->set_unscaled_clock(m_okim6295_clock[1]);
}
}
if(version >= 0x161 && r32(0x9c)) {
m_k051649->set_unscaled_clock(r32(0x9c));
}
if(version >= 0x161 && r32(0xa0)) {
uint32_t clock = r32(0xa0);
m_k054539[0]->set_unscaled_clock(clock & ~0x40000000);
if (clock & 0x40000000) {
clock &= ~0x40000000;
m_k054539[1]->set_unscaled_clock(clock);
}
}
if(version >= 0x161 && r32(0xac)) {
m_k053260->set_unscaled_clock(r32(0xac));
}
if(version >= 0x161 && r32(0xa4)) {
m_c6280->set_unscaled_clock(r32(0xa4));
}
if(version >= 0x161 && r32(0xb0)) {
uint32_t clock = r32(0xb0);
m_pokey[0]->set_unscaled_clock(clock & ~0x40000000);
if (clock & 0x40000000) {
clock &= ~0x40000000;
m_pokey[1]->set_unscaled_clock(clock);
}
}
if(version >= 0x161 && r32(0xb4)) {
m_qsound->set_unscaled_clock(r32(0xb4) * 15); // * 15 multipler for correct pitch
}
}
m_segapcm->set_unscaled_clock(version >= 0x151 ? r32(0x38) : 0);
m_segapcm->set_bank(version >= 0x151 ? r32(0x3c) : 0);
if (data_start > 0xc0)
{
if(version >= 0x171 && r8(0xd6)) {
m_c352->set_divider(r8(0xd6) * 4);
}
if(version >= 0x171 && r32(0xd8)) {
m_x1_010->set_unscaled_clock(r32(0xd8));
}
if(version >= 0x171 && r32(0xdc)) {
m_c352->set_unscaled_clock(r32(0xdc));
}
if(version >= 0x171 && r32(0xe0)) {
m_ga20->set_unscaled_clock(r32(0xe0));
}
}
m_rf5c68->set_unscaled_clock(version >= 0x151 ? r32(0x40) : 0);
m_ym2203[0]->set_unscaled_clock(version >= 0x151 ? r32(0x44) & ~0x40000000 : 0);
m_ym2203[1]->set_unscaled_clock(version >= 0x151 && (r32(0x44) & 0x40000000) ? r32(0x44) & ~0x40000000 : 0);
m_ym2608->set_unscaled_clock(version >= 0x151 ? r32(0x48) & ~0x40000000 : 0);
if (version >= 0x151 && (r32(0x48) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd YM2608\n");
m_vgmplay->reset();
if (version >= 0x151 && r32(0x4c))
logerror("Warning: file requests an unsupported %s\n", r32(0x4c) & 0x80000000 ? "YM2610B" : "YM2610");
m_ym3812->set_unscaled_clock(version >= 0x151 ? r32(0x50) & ~0x40000000 : 0);
if (version >= 0x151 && (r32(0x50) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd YM3812\n");
m_ym3526->set_unscaled_clock(version >= 0x151 ? r32(0x54) & ~0x40000000 : 0);
if (version >= 0x151 && (r32(0x54) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd YM3526\n");
if(version >= 0x151 && r32(0x58))
logerror("Warning: file requests an unsupported Y8950\n");
if(version >= 0x151 && r32(0x5c))
logerror("Warning: file requests an unsupported YMF262\n");
if(version >= 0x151 && r32(0x60))
logerror("Warning: file requests an unsupported YMF278B\n");
m_ymf271->set_unscaled_clock(version >= 0x151 ? r32(0x64) & ~0x40000000 : 0);
if (version >= 0x151 && (r32(0x64) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd YMF271\n");
m_ymz280b->set_unscaled_clock(version >= 0x151 ? r32(0x68) & ~0x40000000 : 0);
if (version >= 0x151 && (r32(0x68) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd YMZ280B\n");
m_rf5c164->set_unscaled_clock(version >= 0x151 ? r32(0x6c) : 0);
if(version >= 0x151 && r32(0x70))
logerror("Warning: file requests an unsupported PWM\n");
m_ay8910[0]->set_unscaled_clock(version >= 0x151 ? r32(0x74) & ~0x40000000 : 0);
m_ay8910[1]->set_unscaled_clock(version >= 0x151 && (r32(0x74) & 0x40000000) ? r32(0x74) & ~0x40000000 : 0);
m_ay8910[0]->set_psg_type(vgm_ay8910_type(version >= 0x151 ? r8(0x78) : 0));
m_ay8910[1]->set_psg_type(vgm_ay8910_type(version >= 0x151 ? r8(0x78) : 0));
m_ay8910[0]->set_flags(vgm_ay8910_flags(version >= 0x151 ? r8(0x79) : 0));
m_ay8910[1]->set_flags(vgm_ay8910_flags(version >= 0x151 ? r8(0x79) : 0));
m_ym2203[0]->set_flags(vgm_ay8910_flags(version >= 0x151 ? r8(0x7a) : 0));
m_ym2203[1]->set_flags(vgm_ay8910_flags(version >= 0x151 ? r8(0x7a) : 0));
m_ym2608->set_flags(vgm_ay8910_flags(version >= 0x151 ? r8(0x7b) : 0));
m_dmg->set_unscaled_clock(version >= 0x161 ? r32(0x80) & ~0x40000000 : 0);
if (version >= 0x161 && (r32(0x80) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd DMG\n");
m_nescpu->set_unscaled_clock(version >= 0x161 ? r32(0x84) & ~0x40000000 : 0);
m_nescpu->m_apu->set_unscaled_clock(version >= 0x161 ? r32(0x84) & ~0x40000000 : 0);
if (version >= 0x161 && (r32(0x84) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd NES APU\n");
m_multipcm[0]->set_unscaled_clock(version >= 0x161 ? r32(0x88) & ~0x40000000 : 0);
m_multipcm[1]->set_unscaled_clock(version >= 0x161 && (r32(0x88) & 0x40000000) ? r32(0x88) & ~0x40000000 : 0);
if (version >= 0x161 && r32(0x8c))
logerror("Warning: file requests an unsupported uPD7759\n");
if (version >= 0x161 && r32(0x90))
logerror("Warning: file requests an unsupported OKIM6258\n");
m_k054539[0]->init_flags(version >= 0x161 ? r8(0x95) : 0);
m_k054539[1]->init_flags(version >= 0x161 ? r8(0x95) : 0);
m_okim6295_clock[0] = version >= 0x161 ? r32(0x98) & 0xc0000000 : 0;
m_okim6295_clock[1] = version >= 0x161 && (r32(0x98) & 0x40000000) ? r32(0x98) & 0xc0000000 : 0;
m_okim6295[0]->set_unscaled_clock(m_okim6295_clock[0]);
m_okim6295[1]->set_unscaled_clock(m_okim6295_clock[1]);
m_okim6295_pin7[0] = version >= 0x161 && (r32(0x98) & 0x80000000) ? 1 : 0;
m_okim6295_pin7[1] = version >= 0x161 && (r32(0x98) & 0x40000000) && (r32(0x98) & 0x80000000) ? 1 : 0;
m_okim6295[0]->set_pin7(m_okim6295_pin7[0] ? okim6295_device::PIN7_HIGH : okim6295_device::PIN7_LOW);
m_okim6295[1]->set_pin7(m_okim6295_pin7[1] ? okim6295_device::PIN7_HIGH : okim6295_device::PIN7_LOW);
m_k051649->set_unscaled_clock(version >= 0x161 ? r32(0x9c) & ~0x40000000 : 0);
if (version >= 0x161 && (r32(0x9c) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd K051649\n");
m_k054539[0]->set_unscaled_clock(version >= 0x161 ? r32(0xa0) & ~0x40000000 : 0);
m_k054539[1]->set_unscaled_clock(version >= 0x161 && (r32(0xa0) & 0x40000000) ? r32(0xa0) & ~0x40000000 : 0);
m_c6280->set_unscaled_clock(version >= 0x161 ? r32(0xa4) & ~0x40000000 : 0);
if (version >= 0x161 && (r32(0xa4) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd C6280\n");
if (version >= 0x161 && r32(0x90))
logerror("Warning: file requests an unsupported C140\n");
m_k053260->set_unscaled_clock(version >= 0x161 ? r32(0xac) & ~0x40000000 : 0);
if (version >= 0x161 && (r32(0xac) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd K053260\n");
m_pokey[0]->set_unscaled_clock(version >= 0x161 ? r32(0xb0) & ~0x40000000 : 0);
m_pokey[1]->set_unscaled_clock(version >= 0x161 && (r32(0xb0) & 0x40000000) ? r32(0xb0) & ~0x40000000 : 0);
m_qsound->set_unscaled_clock(version >= 0x161 ? r32(0xb4) * 15 : 0); // * 15 multipler for correct pitch
if (version >= 0x151 && r32(0xb8))
logerror("Warning: file requests an unsupported SCSP\n");
if (version >= 0x151 && r32(0xc0))
logerror("Warning: file requests an unsupported WonderSwan\n");
if (version >= 0x151 && r32(0xc4))
logerror("Warning: file requests an unsupported VSU\n");
if (version >= 0x151 && r32(0xc8))
logerror("Warning: file requests an unsupported SAA1099\n");
if (version >= 0x151 && r32(0xcc))
logerror("Warning: file requests an unsupported ES5503\n");
if (version >= 0x151 && r32(0xd0))
logerror("Warning: file requests an unsupported %s\n", r32(0xd0) & 0x80000000 ? "ES5506" : "ES5505");
m_c352->set_divider(version >= 0x171 && r8(0xd6) ? r8(0xd6) * 4 : 1);
m_x1_010->set_unscaled_clock(version >= 0x171 ? r32(0xd8) & ~0x40000000 : 0);
if (version >= 0x171 && (r32(0xd8) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd X1-010\n");
m_c352->set_unscaled_clock(version >= 0x171 ? r32(0xdc) & ~0x40000000 : 0);
if (version >= 0x171 && (r32(0xd8) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd C352\n");
m_ga20->set_unscaled_clock(version >= 0x171 ? r32(0xe0) & ~0x40000000 : 0);
if (version >= 0x171 && (r32(0xd8) & 0x40000000))
logerror("Warning: file requests an unsupported 2nd GA20\n");
machine().schedule_soft_reset();
return image_init_result::PASS;
}
@ -2008,69 +1988,68 @@ MACHINE_CONFIG_START(vgmplay_state::vgmplay)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
MCFG_DEVICE_ADD("ym2612", YM2612, 7670454)
MCFG_DEVICE_ADD("ym2612", YM2612, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("ym2151", YM2151, 3579545)
MCFG_DEVICE_ADD("ym2151", YM2151, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("ym2413", YM2413, 3579545)
MCFG_DEVICE_ADD("ym2413", YM2413, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1)
MCFG_DEVICE_ADD("sn76496", SN76496, 3579545)
MCFG_DEVICE_ADD("sn76496", SN76496, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.5)
MCFG_SOUND_ROUTE(0, "rspeaker", 0.5)
MCFG_DEVICE_ADD("segapcm", SEGAPCM, 4000000)
MCFG_DEVICE_ADD("segapcm", SEGAPCM, 0)
MCFG_SEGAPCM_BANK(BANK_512) // Should be configurable for yboard...
MCFG_DEVICE_ADDRESS_MAP(0, segapcm_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("multipcma", MULTIPCM, 8000000)
MCFG_DEVICE_ADD("multipcma", MULTIPCM, 0)
MCFG_DEVICE_ADDRESS_MAP(0, multipcma_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("multipcmb", MULTIPCM, 8000000)
MCFG_DEVICE_ADD("multipcmb", MULTIPCM, 0)
MCFG_DEVICE_ADDRESS_MAP(0, multipcmb_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("dmg", DMG_APU, XTAL(4'194'304))
MCFG_DEVICE_ADD("dmg", DMG_APU, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("ay8910a", AY8910, 1500000)
MCFG_DEVICE_ADD("ay8910a", AY8910, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.33)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.33)
MCFG_DEVICE_ADD("ay8910b", AY8910, 1500000)
MCFG_DEVICE_ADD("ay8910b", AY8910, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.33)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.33)
MCFG_DEVICE_ADD("ym2203a", YM2203, 4000000)
MCFG_DEVICE_ADD("ym2203a", YM2203, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.25)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.25)
MCFG_DEVICE_ADD("ym2203b", YM2203, 4000000)
MCFG_DEVICE_ADD("ym2203b", YM2203, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.25)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.25)
MCFG_DEVICE_ADD("ym3526", YM3526, 4000000)
MCFG_DEVICE_ADD("ym3526", YM3526, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.5)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.5)
MCFG_DEVICE_ADD("ym3812", YM3812, 4000000)
MCFG_DEVICE_ADD("ym3812", YM3812, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.50)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.50)
MCFG_DEVICE_ADD("nescpu", N2A03, 1000000)
MCFG_DEVICE_ADD("nescpu", N2A03, 0)
MCFG_DEVICE_PROGRAM_MAP(nescpu_map)
MCFG_DEVICE_DISABLE()
MCFG_DEVICE_MODIFY("nescpu:nesapu")
MCFG_SOUND_ROUTES_RESET()
@ -2082,90 +2061,90 @@ MACHINE_CONFIG_START(vgmplay_state::vgmplay)
MCFG_DEVICE_IO_MAP(h6280_io_map)
MCFG_DEVICE_DISABLE()
MCFG_DEVICE_ADD("c6280", C6280, 3579545)
MCFG_DEVICE_ADD("c6280", C6280, 0)
MCFG_C6280_CPU("h6280")
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_K053260_ADD("k053260", 3579545)
MCFG_K053260_ADD("k053260", 0)
MCFG_DEVICE_ADDRESS_MAP(0, k053260_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("pokeya", POKEY, 1789772)
MCFG_DEVICE_ADD("pokeya", POKEY, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.5)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.5)
MCFG_DEVICE_ADD("pokeyb", POKEY, 1789772)
MCFG_DEVICE_ADD("pokeyb", POKEY, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.5)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.5)
MCFG_DEVICE_ADD("c352", C352, 1000000, 288)
MCFG_DEVICE_ADD("c352", C352, 0, 1)
MCFG_DEVICE_ADDRESS_MAP(0, c352_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("okim6295a", OKIM6295, 1000000, okim6295_device::PIN7_HIGH)
MCFG_DEVICE_ADD("okim6295a", OKIM6295, 0, okim6295_device::PIN7_HIGH)
MCFG_DEVICE_ADDRESS_MAP(0, okim6295a_map)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.25)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.25)
MCFG_DEVICE_ADD("okim6295b", OKIM6295, 1000000, okim6295_device::PIN7_HIGH)
MCFG_DEVICE_ADD("okim6295b", OKIM6295, 0, okim6295_device::PIN7_HIGH)
MCFG_DEVICE_ADDRESS_MAP(0, okim6295b_map)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.25)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.25)
MCFG_DEVICE_ADD("ymf271", YMF271, 16934400)
MCFG_DEVICE_ADD("ymf271", YMF271, 0)
MCFG_DEVICE_ADDRESS_MAP(0, ymf271_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("ymz280b", YMZ280B, 16934400)
MCFG_DEVICE_ADD("ymz280b", YMZ280B, 0)
MCFG_DEVICE_ADDRESS_MAP(0, ymz280b_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("ym2608", YM2608, 8000000)
MCFG_DEVICE_ADD("ym2608", YM2608, 0)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.25)
MCFG_SOUND_ROUTE(0, "rspeaker", 0.25)
MCFG_SOUND_ROUTE(1, "lspeaker", 0.50)
MCFG_SOUND_ROUTE(2, "rspeaker", 0.50)
MCFG_DEVICE_ADD("k054539a", K054539, XTAL(18'432'000))
MCFG_DEVICE_ADD("k054539a", K054539, 0)
MCFG_DEVICE_ADDRESS_MAP(0, k054539a_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("k054539b", K054539, XTAL(18'432'000))
MCFG_DEVICE_ADD("k054539b", K054539, 0)
MCFG_DEVICE_ADDRESS_MAP(0, k054539b_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_DEVICE_ADD("qsound", QSOUND)
MCFG_DEVICE_ADD("qsound", QSOUND, 0)
MCFG_DEVICE_ADDRESS_MAP(0, qsound_map)
MCFG_SOUND_ROUTE(0, "lspeaker", 1)
MCFG_SOUND_ROUTE(1, "rspeaker", 1)
MCFG_K051649_ADD("k051649", 3579545)
MCFG_K051649_ADD("k051649", 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.33)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.33)
IREMGA20(config, m_ga20, 3579545);
IREMGA20(config, m_ga20, 0);
m_ga20->set_addrmap(0, &vgmplay_state::ga20_map);
m_ga20->add_route(0, "lspeaker", 1);
m_ga20->add_route(1, "rspeaker", 1);
RF5C68(config, m_rf5c68, 12500000);
RF5C68(config, m_rf5c68, 0);
m_rf5c68->set_addrmap(0, &vgmplay_state::rf5c68_map);
m_rf5c68->add_route(0, "lspeaker", 1);
m_rf5c68->add_route(1, "rspeaker", 1);
RF5C68(config, m_rf5c164, 12500000); // TODO : !!RF5C164!!
RF5C68(config, m_rf5c164, 0); // TODO : !!RF5C164!!
m_rf5c164->set_addrmap(0, &vgmplay_state::rf5c164_map);
m_rf5c164->add_route(0, "lspeaker", 1);
m_rf5c164->add_route(1, "rspeaker", 1);
X1_010(config, m_x1_010, 16000000);
X1_010(config, m_x1_010, 0);
m_x1_010->set_addrmap(0, &vgmplay_state::x1_010_map);
m_x1_010->add_route(0, "lspeaker", 1);
m_x1_010->add_route(1, "rspeaker", 1);