From f521d742ba0d65578e7d0e0010b90ec60422c3ff Mon Sep 17 00:00:00 2001 From: David Haywood Date: Tue, 13 Nov 2018 22:57:58 +0000 Subject: XaviX - add rate control to sound (#4290) * XaviX - add rate control to sound * make sound stereo (nw) * (nw) * improved logging of sound (nw) * (nw) * maybe, allows monster truck race start sample to complete, but then other sounds go missing (nw) * new e-kara Software List entries [Team Europe + contributors] e-kara UK / Europe Volume 2 (UK-E002) e-kara UK / Europe Volume 3 (UK-E003) e-kara UK / Europe Volume 6 (UK-E006) also verified UK vols 1 + 7 on second cartridges, and documented what UK volumes 4+5 are (the collection that was picked up came with a sale sheet advertising them all, complete with track listings) * note * same note here (nw) * typo (nw) * minor changes (nw) --- hash/ekara.xml | 102 ++++++++++++++++- src/mame/audio/xavix.cpp | 279 +++++++++++++++++++++++++++++++++------------ src/mame/drivers/xavix.cpp | 13 ++- src/mame/includes/xavix.h | 25 ++-- src/mame/machine/xavix.cpp | 18 +-- 5 files changed, 338 insertions(+), 99 deletions(-) diff --git a/hash/ekara.xml b/hash/ekara.xml index 05261937812..0064b20dd2c 100644 --- a/hash/ekara.xml +++ b/hash/ekara.xml @@ -212,7 +212,7 @@ - - e-kara UK / Europe Volume 1 (UK-E001) 2002 @@ -236,6 +235,101 @@ + + + e-kara UK / Europe Volume 2 (UK-E002) + 2002 + Takara + + + + + + + + + + e-kara UK / Europe Volume 3 (UK-E003) + 2002 + Takara + + + + + + + + + + + + + + e-kara UK / Europe Volume 6 (UK-E006) + 2002 + Takara + + + + + + + - + BHT Volume 1 (Japan) (GC0002-BHT) 2000 Takara diff --git a/src/mame/audio/xavix.cpp b/src/mame/audio/xavix.cpp index 03941dc9b7d..ff7f0d5b596 100644 --- a/src/mame/audio/xavix.cpp +++ b/src/mame/audio/xavix.cpp @@ -27,15 +27,17 @@ void xavix_sound_device::device_start() m_readregs_cb.resolve_safe(0xff); m_readsamples_cb.resolve_safe(0x80); - m_stream = stream_alloc(0, 1, 8000); + m_stream = stream_alloc(0, 2, 163840); } void xavix_sound_device::device_reset() { for (int v = 0; v < 16; v++) { - m_voice[v].enabled = false; - m_voice[v].position = 0x00; + m_voice[v].enabled[0] = false; + m_voice[v].enabled[1] = false; + m_voice[v].position[0] = 0x00; + m_voice[v].position[1] = 0x00; m_voice[v].bank = 0x00; } } @@ -45,27 +47,50 @@ void xavix_sound_device::sound_stream_update(sound_stream &stream, stream_sample { // reset the output stream memset(outputs[0], 0, samples * sizeof(*outputs[0])); + memset(outputs[1], 0, samples * sizeof(*outputs[1])); int outpos = 0; // loop while we still have samples to generate while (samples-- != 0) { - for (int v = 0; v < 16; v++) + for (int channel = 0; channel < 2; channel++) { - if (m_voice[v].enabled == true) + for (int v = 0; v < 16; v++) { - if (m_voice[v].type == 2 || m_voice[v].type == 3) + if (m_voice[v].enabled[channel] == true) { - int8_t sample = m_readsamples_cb((m_voice[v].bank << 16) | m_voice[v].position); - - if ((uint8_t)sample == 0x80) + // 2 is looping? 3 is single shot? 0/1 are something else? + if (m_voice[v].type == 2 || m_voice[v].type == 3) { - m_voice[v].enabled = false; - break; + uint32_t pos = (m_voice[v].bank << 16) | (m_voice[v].position[channel] >> 14); + int8_t sample = m_readsamples_cb(pos); + + if ((uint8_t)sample == 0x80) // would both channels stop / loop or just one?, Yellow submarine indicates just one, but might be running in some interleaved mode? + { + //if (m_voice[v].type == 3) + { + m_voice[v].enabled[channel] = false; + break; + } + /* need envelopes or some of these loop forever! + else if (m_voice[v].type == 2) + { + m_voice[v].position[channel] = m_voice[v].startposition[channel]; + // presumably don't want to play 0x80 byte, so read in a new one + pos = (m_voice[v].bank << 16) | (m_voice[v].position[channel] >> 14); + sample = m_readsamples_cb(pos); + } + */ + } + + outputs[channel][outpos] += sample * (m_voice[v].vol + 1); + m_voice[v].position[channel] += m_voice[v].rate; + } + else + { + popmessage("unsupported voice type %01x", m_voice[v].type); + m_voice[v].enabled[channel] = false; } - - outputs[0][outpos] += sample * 0x10; - m_voice[v].position++; } } } @@ -73,45 +98,120 @@ void xavix_sound_device::sound_stream_update(sound_stream &stream, stream_sample } } -void xavix_sound_device::enable_voice(int voice) +bool xavix_sound_device::is_voice_enabled(int voice) { - LOG("voice %d 0->1 ", voice); + m_stream->update(); + +/* + if ((m_voice[voice].enabled[0] == true) || (m_voice[voice].enabled[1] == true)) + return true; + else + return false; +*/ + if ((m_voice[voice].enabled[0] == true) && (m_voice[voice].enabled[1] == true)) + return true; + else + return false; +} + + +void xavix_sound_device::enable_voice(int voice, bool update_only) +{ + m_stream->update(); + int voicemembase = voice * 0x10; - uint16_t param1 = (m_readregs_cb(voicemembase + 0x1) << 8) | (m_readregs_cb(voicemembase + 0x0)); // sample rate maybe? - uint16_t param2 = (m_readregs_cb(voicemembase + 0x3) << 8) | (m_readregs_cb(voicemembase + 0x2)); // seems to be a start position - uint16_t param3 = (m_readregs_cb(voicemembase + 0x5) << 8) | (m_readregs_cb(voicemembase + 0x4)); // another start position? sometimes same as param6 - uint8_t param4a = (m_readregs_cb(voicemembase + 0x7)); - uint8_t param4b = (m_readregs_cb(voicemembase + 0x6)); // upper 8 bits of memory address? 8 bits unused? + uint16_t freq_mode = (m_readregs_cb(voicemembase + 0x1) << 8) | (m_readregs_cb(voicemembase + 0x0)); // sample rate maybe? + uint16_t sampleaddrleft = (m_readregs_cb(voicemembase + 0x3) << 8) | (m_readregs_cb(voicemembase + 0x2)); // seems to be a start position + uint16_t sampleaddrright = (m_readregs_cb(voicemembase + 0x5) << 8) | (m_readregs_cb(voicemembase + 0x4)); // another start position? sometimes same as envaddrleft + uint8_t unused1 = (m_readregs_cb(voicemembase + 0x7)); // data gets written but doesn't look like it's used by the chip? + uint8_t sampleaddrbank = (m_readregs_cb(voicemembase + 0x6)); // upper 8 bits of memory address? 8 bits unused? // these don't seem to be populated as often, maybe some kind of effect / envelope filter? - uint8_t param5a = (m_readregs_cb(voicemembase + 0x9)); - uint8_t param5b = (m_readregs_cb(voicemembase + 0x8)); - uint16_t param6 = (m_readregs_cb(voicemembase + 0xb) << 8) | (m_readregs_cb(voicemembase + 0xa)); // seems to be a start position - uint16_t param7 = (m_readregs_cb(voicemembase + 0xd) << 8) | (m_readregs_cb(voicemembase + 0xc)); // another start position? sometimes same as param6 - uint8_t param8a = (m_readregs_cb(voicemembase + 0xf)); - uint8_t param8b = (m_readregs_cb(voicemembase + 0xe)); // upper 8 bits of memory address? 8 bits unused (or not unused?, get populated with increasing values sometimes?) - LOG(" (params %04x %04x %04x %02x %02x %02x %02x %04x %04x %02x %02x)\n", param1, param2, param3, param4a, param4b, param5a, param5b, param6, param7, param8a, param8b); + uint8_t envfreq = (m_readregs_cb(voicemembase + 0x9)); + uint8_t envmode_unk = (m_readregs_cb(voicemembase + 0x8)); + uint16_t envaddrleft = (m_readregs_cb(voicemembase + 0xb) << 8) | (m_readregs_cb(voicemembase + 0xa)); // seems to be a start position, lower byte is direct value, not address in some modes?? + uint16_t envaddrright = (m_readregs_cb(voicemembase + 0xd) << 8) | (m_readregs_cb(voicemembase + 0xc)); // another start position? sometimes same as envaddrleft + uint8_t unused2 = (m_readregs_cb(voicemembase + 0xf)); // data gets written but doesn't look like it's used by the chip? + uint8_t envaddrbank = (m_readregs_cb(voicemembase + 0xe)); // upper 8 bits of memory address? 8 bits unused (or not unused?, get populated with increasing values sometimes?) + + uint32_t sampleaddrleft_full = (sampleaddrleft | sampleaddrbank << 16) & 0x00ffffff; // definitely addresses based on rad_snow + uint32_t sampleaddrright_full = (sampleaddrright | sampleaddrbank << 16) & 0x00ffffff; - uint32_t address1 = (param2 | param4b << 16) & 0x00ffffff; // definitely addresses based on rad_snow - uint32_t address2 = (param3 | param4b << 16) & 0x00ffffff; + uint32_t envaddrleft_full = (envaddrleft | envaddrbank << 16) & 0x00ffffff; // still looks like addresses, sometimes pointing at RAM + uint32_t envaddrright_full = (envaddrright | envaddrbank << 16) & 0x00ffffff; - uint32_t address3 = (param6 | param8b << 16) & 0x00ffffff; // still looks like addresses, sometimes pointing at RAM - uint32_t address4 = (param7 | param8b << 16) & 0x00ffffff; + uint8_t envmode = (envmode_unk >> 4)&3; // upper bits not used? + uint8_t envunk = envmode_unk & 0x0f; + if (update_only) LOG("(UPDATE ONLY) "); - LOG(" (possible meanings mode %01x rate %04x address1 %08x address2 %08x address3 %08x address4 %08x)\n", param1 & 0x3, param1 >> 2, address1, address2, address3, address4); + LOG("voice %01x (params %04x %04x %04x %02x %02x %02x %02x %04x %04x %02x %02x)\n", voice, freq_mode, sampleaddrleft, sampleaddrright, unused1, sampleaddrbank, envfreq, envmode_unk, envaddrleft, envaddrright, unused2, envaddrbank); - m_voice[voice].enabled = true; + if (envmode == 0) + { + // mode 0 doesn't seem to use a second pair of addresses for the envelope but instead a fixed value in the lower part of the address registers?, usually used with non-looping samples too? upper bytes of address end up being leftovers from previous sounds + LOG("voice %01x (possible meanings mode %01x rate %04x sampleaddrleft_full %08x sampleaddrright_full %08x envvalue_left %02x envvalue_right %02x envfreq %02x envmode_unk [%01x, %01x])\n", voice, freq_mode & 0x3, freq_mode >> 2, sampleaddrleft_full, sampleaddrright_full, envaddrleft_full & 0xff, envaddrright_full & 0xff, envfreq, envmode, envunk); + } + else + { + // envelopes usually point to 8-byte sequences of values? + // when written from sound_updateenv_w (update only) then mode is usually 0x3 (key off?) + // mode 1 is used for most samples (key on?) + // mode 2 is used on monster truck + + LOG("voice %01x (possible meanings mode %01x rate %04x sampleaddrleft_full %08x sampleaddrright_full %08x envaddrleft_full %08x envaddrright_full %08x envfreq %02x envmode_unk [%01x, %01x])\n", voice, freq_mode & 0x3, freq_mode >> 2, sampleaddrleft_full, sampleaddrright_full, envaddrleft_full, envaddrright_full, envfreq, envmode, envunk); + + LOG(" (ENV1 "); + for (int i = 0; i < 8; i++) + { + uint8_t env = m_readsamples_cb(envaddrleft_full+i); + LOG("%02x ", env); + } + LOG(") "); - m_voice[voice].bank = param4b; - m_voice[voice].position = param2; // param3 - m_voice[voice].type = param1 & 0x3; + LOG(" (ENV2 "); + for (int i = 0; i < 8; i++) + { + uint8_t env = m_readsamples_cb(envaddrright_full+i); + LOG("%02x ", env); + } + LOG(") \n"); + } + + if (envmode_unk & 0xc0) + { + LOG(" (unexpected bits set in envmode_unk %02x)\n", envmode_unk & 0xc0); + } + + if (!update_only) + { + m_voice[voice].enabled[0] = true; + m_voice[voice].enabled[1] = true; + + m_voice[voice].bank = sampleaddrbank; + m_voice[voice].position[0] = sampleaddrleft << 14; + m_voice[voice].position[1] = sampleaddrright << 14; + m_voice[voice].type = freq_mode & 0x3; + m_voice[voice].rate = freq_mode >> 2; + m_voice[voice].vol = envunk; + + m_voice[voice].startposition[0] = m_voice[voice].position[0]; // for looping + m_voice[voice].startposition[1] = m_voice[voice].position[1]; + } + + // 0320 (800) == 8000hz + // 4000 (16384) == 163840hz ? = 163.840kHz - // samples appear to be PCM, 0x80 terminated + // samples appear to be PCM, 0x80 terminated, looks like there's a way of specifying mono (interleave channels?) or stereo, maybe in master regs? } +void xavix_sound_device::disable_voice(int voice) +{ + m_voice[voice].enabled[0] = false; + m_voice[voice].enabled[1] = false; +} // xavix_state support @@ -131,13 +231,13 @@ READ8_MEMBER(xavix_state::sound_regram_read_cb) /* 75f0, 75f1 - 2x8 bits (16 voices?) */ -READ8_MEMBER(xavix_state::sound_reg16_0_r) +READ8_MEMBER(xavix_state::sound_startstop_r) { - LOG("%s: sound_reg16_0_r %02x\n", machine().describe_context(), offset); + LOG("%s: sound_startstop_r %02x\n", machine().describe_context(), offset); return m_soundreg16_0[offset]; } -WRITE8_MEMBER(xavix_state::sound_reg16_0_w) +WRITE8_MEMBER(xavix_state::sound_startstop_w) { /* looks like the sound triggers @@ -162,65 +262,96 @@ WRITE8_MEMBER(xavix_state::sound_reg16_0_w) data & 0x80 - voice 15 (registers at regbase + 0xf0) eg 0x3bf0 - 0x3bff in monster truck */ if (offset == 0) - LOG("%s: sound_reg16_0_w %02x, %02x (%d %d %d %d %d %d %d %d - - - - - - - -)\n", machine().describe_context(), offset, data, (data & 0x01) ? 1 : 0, (data & 0x02) ? 1 : 0, (data & 0x04) ? 1 : 0, (data & 0x08) ? 1 : 0, (data & 0x10) ? 1 : 0, (data & 0x20) ? 1 : 0, (data & 0x40) ? 1 : 0, (data & 0x80) ? 1 : 0); + LOG("%s: sound_startstop_w %02x, %02x (%d %d %d %d %d %d %d %d - - - - - - - -)\n", machine().describe_context(), offset, data, (data & 0x01) ? 1 : 0, (data & 0x02) ? 1 : 0, (data & 0x04) ? 1 : 0, (data & 0x08) ? 1 : 0, (data & 0x10) ? 1 : 0, (data & 0x20) ? 1 : 0, (data & 0x40) ? 1 : 0, (data & 0x80) ? 1 : 0); else - LOG("%s: sound_reg16_0_w %02x, %02x (- - - - - - - - %d %d %d %d %d %d %d %d)\n", machine().describe_context(), offset, data, (data & 0x01) ? 1 : 0, (data & 0x02) ? 1 : 0, (data & 0x04) ? 1 : 0, (data & 0x08) ? 1 : 0, (data & 0x10) ? 1 : 0, (data & 0x20) ? 1 : 0, (data & 0x40) ? 1 : 0, (data & 0x80) ? 1 : 0); + LOG("%s: sound_startstop_w %02x, %02x (- - - - - - - - %d %d %d %d %d %d %d %d)\n", machine().describe_context(), offset, data, (data & 0x01) ? 1 : 0, (data & 0x02) ? 1 : 0, (data & 0x04) ? 1 : 0, (data & 0x08) ? 1 : 0, (data & 0x10) ? 1 : 0, (data & 0x20) ? 1 : 0, (data & 0x40) ? 1 : 0, (data & 0x80) ? 1 : 0); for (int i = 0; i < 8; i++) { - int voice_state = (data & (1 << i)); - int old_voice_state = (m_soundreg16_0[offset] & (1 << i)); + const int voice_state = (data & (1 << i)); + const int old_voice_state = (m_soundreg16_0[offset] & (1 << i)); if (voice_state != old_voice_state) { + const int voice = (offset * 8 + i); + if (voice_state) { - int voice = (offset * 8 + i); - - m_sound->enable_voice(voice); + m_sound->enable_voice(voice, false); + } + else + { + m_sound->disable_voice(voice); } } } m_soundreg16_0[offset] = data; - } /* 75f0, 75f1 - 2x8 bits (16 voices?) */ -READ8_MEMBER(xavix_state::sound_reg16_1_r) +READ8_MEMBER(xavix_state::sound_updateenv_r) { - LOG("%s: sound_reg16_1_r %02x\n", machine().describe_context(), offset); + LOG("%s: sound_updateenv_r %02x\n", machine().describe_context(), offset); return m_soundreg16_1[offset]; } -WRITE8_MEMBER(xavix_state::sound_reg16_1_w) +WRITE8_MEMBER(xavix_state::sound_updateenv_w) { - m_soundreg16_1[offset] = data; - if (offset == 0) - LOG("%s: sound_reg16_1_w %02x, %02x (%d %d %d %d %d %d %d %d - - - - - - - -)\n", machine().describe_context(), offset, data, (data & 0x01) ? 1 : 0, (data & 0x02) ? 1 : 0, (data & 0x04) ? 1 : 0, (data & 0x08) ? 1 : 0, (data & 0x10) ? 1 : 0, (data & 0x20) ? 1 : 0, (data & 0x40) ? 1 : 0, (data & 0x80) ? 1 : 0); + LOG("%s: sound_updateenv_w %02x, %02x (%d %d %d %d %d %d %d %d - - - - - - - -)\n", machine().describe_context(), offset, data, (data & 0x01) ? 1 : 0, (data & 0x02) ? 1 : 0, (data & 0x04) ? 1 : 0, (data & 0x08) ? 1 : 0, (data & 0x10) ? 1 : 0, (data & 0x20) ? 1 : 0, (data & 0x40) ? 1 : 0, (data & 0x80) ? 1 : 0); else - LOG("%s: sound_reg16_1_w %02x, %02x (- - - - - - - - %d %d %d %d %d %d %d %d)\n", machine().describe_context(), offset, data, (data & 0x01) ? 1 : 0, (data & 0x02) ? 1 : 0, (data & 0x04) ? 1 : 0, (data & 0x08) ? 1 : 0, (data & 0x10) ? 1 : 0, (data & 0x20) ? 1 : 0, (data & 0x40) ? 1 : 0, (data & 0x80) ? 1 : 0); + LOG("%s: sound_updateenv_w %02x, %02x (- - - - - - - - %d %d %d %d %d %d %d %d)\n", machine().describe_context(), offset, data, (data & 0x01) ? 1 : 0, (data & 0x02) ? 1 : 0, (data & 0x04) ? 1 : 0, (data & 0x08) ? 1 : 0, (data & 0x10) ? 1 : 0, (data & 0x20) ? 1 : 0, (data & 0x40) ? 1 : 0, (data & 0x80) ? 1 : 0); + + // used to update envelopes without restarting sound? for key-off events? + for (int i = 0; i < 8; i++) + { + const int voice_state = (data & (1 << i)); + const int old_voice_state = (m_soundreg16_1[offset] & (1 << i)); + if (voice_state != old_voice_state) + { + const int voice = (offset * 8 + i); + + if (voice_state) + { + m_sound->enable_voice(voice, true); + } + else + { + m_sound->disable_voice(voice); + } + } + } + + m_soundreg16_1[offset] = data; } /* 75f4, 75f5 - 2x8 bits (16 voices?) status? */ READ8_MEMBER(xavix_state::sound_sta16_r) { - // used with 75f0/75f1 - return machine().rand(); + uint8_t ret = 0x00; + + for (int i = 0; i < 8; i++) + { + const int voice = (offset * 8 + i); + const bool enabled = m_sound->is_voice_enabled(voice); + ret |= enabled ? 1 << i : 0; + } + + return ret; } /* 75f6 - master volume control? */ READ8_MEMBER(xavix_state::sound_volume_r) { LOG("%s: sound_volume_r\n", machine().describe_context()); - return m_soundregs[6]; + return m_mastervol; } WRITE8_MEMBER(xavix_state::sound_volume_w) { - m_soundregs[6] = data; + m_mastervol = data; LOG("%s: sound_volume_w %02x\n", machine().describe_context(), data); } @@ -239,25 +370,25 @@ WRITE8_MEMBER(xavix_state::sound_regbase_w) READ8_MEMBER(xavix_state::sound_75f8_r) { LOG("%s: sound_75f8_r\n", machine().describe_context()); - return m_soundregs[8]; + return m_unk_snd75f8; } WRITE8_MEMBER(xavix_state::sound_75f8_w) { - m_soundregs[8] = data; + m_unk_snd75f8 = data; LOG("%s: sound_75f8_w %02x\n", machine().describe_context(), data); } READ8_MEMBER(xavix_state::sound_75f9_r) { LOG("%s: sound_75f9_r\n", machine().describe_context()); - return 0x00; + return m_unksnd75f9; } WRITE8_MEMBER(xavix_state::sound_75f9_w) { - m_soundregs[9] = data; - LOG("%s: sound_75f9_w %02x\n", machine().describe_context(), data); + m_unksnd75f9 = data; + LOG("%s: sound_75f9_w %02x\n", machine().describe_context().c_str(), data); } /* 75fa, 75fb, 75fc, 75fd - timers?? generate interrupts?? */ @@ -265,48 +396,48 @@ WRITE8_MEMBER(xavix_state::sound_75f9_w) READ8_MEMBER(xavix_state::sound_timer0_r) { LOG("%s: sound_timer0_r\n", machine().describe_context()); - return m_soundregs[10]; + return m_sndtimer[0]; } WRITE8_MEMBER(xavix_state::sound_timer0_w) { - m_soundregs[10] = data; + m_sndtimer[0] = data; LOG("%s: sound_timer0_w %02x\n", machine().describe_context(), data); } READ8_MEMBER(xavix_state::sound_timer1_r) { LOG("%s: sound_timer1_r\n", machine().describe_context()); - return m_soundregs[11]; + return m_sndtimer[1]; } WRITE8_MEMBER(xavix_state::sound_timer1_w) { - m_soundregs[11] = data; + m_sndtimer[1] = data; LOG("%s: sound_timer1_w %02x\n", machine().describe_context(), data); } READ8_MEMBER(xavix_state::sound_timer2_r) { LOG("%s: sound_timer2_r\n", machine().describe_context()); - return m_soundregs[12]; + return m_sndtimer[2]; } WRITE8_MEMBER(xavix_state::sound_timer2_w) { - m_soundregs[12] = data; + m_sndtimer[2] = data; LOG("%s: sound_timer2_w %02x\n", machine().describe_context(), data); } READ8_MEMBER(xavix_state::sound_timer3_r) { LOG("%s: sound_timer3_r\n", machine().describe_context()); - return m_soundregs[13]; + return m_sndtimer[3]; } WRITE8_MEMBER(xavix_state::sound_timer3_w) { - m_soundregs[13] = data; + m_sndtimer[3] = data; LOG("%s: sound_timer3_w %02x\n", machine().describe_context(), data); } @@ -340,7 +471,7 @@ WRITE8_MEMBER(xavix_state::sound_irqstatus_w) WRITE8_MEMBER(xavix_state::sound_75ff_w) { - m_soundregs[15] = data; + m_unksnd75ff = data; LOG("%s: sound_75ff_w %02x\n", machine().describe_context(), data); } diff --git a/src/mame/drivers/xavix.cpp b/src/mame/drivers/xavix.cpp index 101aec50079..e571908338d 100644 --- a/src/mame/drivers/xavix.cpp +++ b/src/mame/drivers/xavix.cpp @@ -321,8 +321,8 @@ void xavix_state::xavix_lowbus_map(address_map &map) // map(0x7400, 0x757f) // Sound Control - map(0x75f0, 0x75f1).rw(FUNC(xavix_state::sound_reg16_0_r), FUNC(xavix_state::sound_reg16_0_w)); // r/w tested read/written 8 times in a row - map(0x75f2, 0x75f3).rw(FUNC(xavix_state::sound_reg16_1_r), FUNC(xavix_state::sound_reg16_1_w)); + map(0x75f0, 0x75f1).rw(FUNC(xavix_state::sound_startstop_r), FUNC(xavix_state::sound_startstop_w)); // r/w tested read/written 8 times in a row + map(0x75f2, 0x75f3).rw(FUNC(xavix_state::sound_updateenv_r), FUNC(xavix_state::sound_updateenv_w)); map(0x75f4, 0x75f5).r(FUNC(xavix_state::sound_sta16_r)); // related to 75f0 / 75f1 (read after writing there - rad_mtrk) // taitons1 after 75f7/75f8 map(0x75f6, 0x75f6).rw(FUNC(xavix_state::sound_volume_r), FUNC(xavix_state::sound_volume_w)); // r/w tested @@ -818,12 +818,17 @@ MACHINE_CONFIG_START(xavix_state::xavix) /* sound hardware */ - SPEAKER(config, "mono").front_center(); + //SPEAKER(config, "mono").front_center(); + SPEAKER(config, "lspeaker").front_left(); + SPEAKER(config, "rspeaker").front_right(); XAVIX_SOUND(config, m_sound, MAIN_CLOCK); m_sound->read_regs_callback().set(FUNC(xavix_state::sound_regram_read_cb)); m_sound->read_samples_callback().set(FUNC(xavix_state::sample_read)); - m_sound->add_route(ALL_OUTPUTS, "mono", 1.0); + //m_sound->add_route(ALL_OUTPUTS, "mono", 1.0); + m_sound->add_route(0, "lspeaker", 1.0); + m_sound->add_route(1, "rspeaker", 1.0); + MACHINE_CONFIG_END MACHINE_CONFIG_START(xavix_i2c_state::xavix_i2c_24lc04) diff --git a/src/mame/includes/xavix.h b/src/mame/includes/xavix.h index 063b7983b92..d691f550abf 100644 --- a/src/mame/includes/xavix.h +++ b/src/mame/includes/xavix.h @@ -26,7 +26,9 @@ public: auto read_regs_callback() { return m_readregs_cb.bind(); } auto read_samples_callback() { return m_readsamples_cb.bind(); } - void enable_voice(int voice); + void enable_voice(int voice, bool update_only); + void disable_voice(int voice); + bool is_voice_enabled(int voice); protected: // device-level overrides @@ -40,10 +42,13 @@ private: sound_stream *m_stream; struct xavix_voice { - bool enabled; - uint16_t position; + bool enabled[2]; + uint32_t position[2]; + uint32_t startposition[2]; uint8_t bank; // no samples appear to cross a bank boundary, so likely wraps int type; + int rate; + int vol; }; devcb_read8 m_readregs_cb; @@ -285,10 +290,10 @@ private: DECLARE_READ8_MEMBER(dispctrl_6ff8_r); DECLARE_WRITE8_MEMBER(dispctrl_6ff8_w); - DECLARE_READ8_MEMBER(sound_reg16_0_r); - DECLARE_WRITE8_MEMBER(sound_reg16_0_w); - DECLARE_READ8_MEMBER(sound_reg16_1_r); - DECLARE_WRITE8_MEMBER(sound_reg16_1_w); + DECLARE_READ8_MEMBER(sound_startstop_r); + DECLARE_WRITE8_MEMBER(sound_startstop_w); + DECLARE_READ8_MEMBER(sound_updateenv_r); + DECLARE_WRITE8_MEMBER(sound_updateenv_w); DECLARE_READ8_MEMBER(sound_sta16_r); DECLARE_READ8_MEMBER(sound_75f5_r); @@ -424,7 +429,11 @@ private: uint8_t m_6ff0; uint8_t m_video_ctrl; - uint8_t m_soundregs[0x10]; + uint8_t m_mastervol; + uint8_t m_unk_snd75f8; + uint8_t m_unksnd75f9; + uint8_t m_unksnd75ff; + uint8_t m_sndtimer[4]; uint8_t m_timer_baseval; diff --git a/src/mame/machine/xavix.cpp b/src/mame/machine/xavix.cpp index d68a3426e87..e5463a3a832 100644 --- a/src/mame/machine/xavix.cpp +++ b/src/mame/machine/xavix.cpp @@ -850,15 +850,15 @@ void xavix_state::machine_reset() m_spritereg = 0; - m_soundregs[0] = 0; - m_soundregs[1] = 0; - - m_soundregs[6] = 0; - m_soundregs[8] = 0; - m_soundregs[10] = 0; - m_soundregs[11] = 0; - m_soundregs[12] = 0; - m_soundregs[13] = 0; + m_mastervol = 0x00; + m_unk_snd75f8 = 0x00; + m_unksnd75f9 = 0x00; + m_unksnd75ff = 0x00; + + for (int i = 0; i < 4; i++) + { + m_sndtimer[i] = 0x00; + } std::fill(std::begin(m_multparams), std::end(m_multparams), 0x00); std::fill(std::begin(m_multresults), std::end(m_multresults), 0x00); -- cgit v1.2.3