diff options
author | 2020-04-12 22:27:53 +0200 | |
---|---|---|
committer | 2020-04-12 22:28:40 +0200 | |
commit | c2ca7ea90cf1a6a58da45bf19f711bcf9d8720ca (patch) | |
tree | 66bb415b5cccdf286f2ef172ce6b3e7c6d42063e | |
parent | af82c0eca86eab376474f5771c8aa66c5a68c1d8 (diff) |
ks0164: Make some noise. Someone get me a GM sample rom please? [O. Galibert]
-rw-r--r-- | src/devices/sound/ks0164.cpp | 119 | ||||
-rw-r--r-- | src/devices/sound/ks0164.h | 2 |
2 files changed, 118 insertions, 3 deletions
diff --git a/src/devices/sound/ks0164.cpp b/src/devices/sound/ks0164.cpp index 928234f8697..c9e28eadcc3 100644 --- a/src/devices/sound/ks0164.cpp +++ b/src/devices/sound/ks0164.cpp @@ -50,7 +50,7 @@ void ks0164_device::device_start() space().install_rom(0, rend, ((1 << 23) - 1) ^ rmask, m_mem_region->base()); } - m_stream = stream_alloc(0, 2, 44100); + m_stream = stream_alloc(0, 2, clock()/3/2/2/32); m_mem_cache = space().cache<1, 0, ENDIANNESS_BIG>(); m_timer = timer_alloc(0); @@ -228,14 +228,69 @@ void ks0164_device::bank2_select_w(offs_t, u16 data, u16 mem_mask) u16 ks0164_device::voice_r(offs_t offset) { + m_stream->update(); + logerror("voice read %02x.%02x -> %04x (%04x)\n", m_voice_select & 0x1f, offset, m_sregs[m_voice_select & 0x1f][offset], m_cpu->pc()); return m_sregs[m_voice_select & 0x1f][offset]; } void ks0164_device::voice_w(offs_t offset, u16 data, u16 mem_mask) { + m_stream->update(); + u16 old = m_sregs[m_voice_select & 0x1f][offset]; COMBINE_DATA(&m_sregs[m_voice_select & 0x1f][offset]); - if(1 || m_cpu->pc() < 0x5f94 || m_cpu->pc() > 0x5fc0) - logerror("voice %02x.%02x = %04x (%04x)\n", m_voice_select & 0x1f, offset, m_sregs[m_voice_select & 0x1f][offset], m_cpu->pc()); + if(0) + if(m_cpu->pc() < 0x5f94 || m_cpu->pc() > 0x5fc0) + logerror("voice %02x.%02x = %04x @ %04x (%04x)\n", m_voice_select & 0x1f, offset, m_sregs[m_voice_select & 0x1f][offset], mem_mask, m_cpu->pc()); + if(offset == 0 && (data & 1) && !(old & 1)) + logerror("keyon %02x mode=%04x (%s %c %c %c) cur=%02x%04x.%04x loop=%02x%04x.%04x end=%02x%04x.%04x pitch=%04x 10=%02x/%02x:%02x/%02x 14=%03x/%03x:%03x/%03x 18=%04x/%04x c=%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", + m_voice_select, + + m_sregs[m_voice_select & 0x1f][0x00], + + m_sregs[m_voice_select & 0x1f][0x00] & 0x8000 ? " 8" : "16", + m_sregs[m_voice_select & 0x1f][0x00] & 0x0400 ? 'c' : 'l', + m_sregs[m_voice_select & 0x1f][0x00] & 0x0008 ? '3' : '-', + m_sregs[m_voice_select & 0x1f][0x00] & 0x0004 ? '2' : '-', + + m_sregs[m_voice_select & 0x1f][0x01], // cur + m_sregs[m_voice_select & 0x1f][0x02], + m_sregs[m_voice_select & 0x1f][0x03], + + m_sregs[m_voice_select & 0x1f][0x09], // loop + m_sregs[m_voice_select & 0x1f][0x0a], + m_sregs[m_voice_select & 0x1f][0x0b], + + m_sregs[m_voice_select & 0x1f][0x0d], // end + m_sregs[m_voice_select & 0x1f][0x0e], + m_sregs[m_voice_select & 0x1f][0x0f], + + m_sregs[m_voice_select & 0x1f][0x08], // pitch + + m_sregs[m_voice_select & 0x1f][0x10] >> 9, + m_sregs[m_voice_select & 0x1f][0x12] >> 9, + m_sregs[m_voice_select & 0x1f][0x11] >> 9, + m_sregs[m_voice_select & 0x1f][0x13] >> 9, + + m_sregs[m_voice_select & 0x1f][0x14] >> 5, + m_sregs[m_voice_select & 0x1f][0x16] >> 5, + m_sregs[m_voice_select & 0x1f][0x15] >> 5, + m_sregs[m_voice_select & 0x1f][0x17] >> 5, + + m_sregs[m_voice_select & 0x1f][0x18], + m_sregs[m_voice_select & 0x1f][0x1c], + + m_sregs[m_voice_select & 0x1f][0x0c], + + m_sregs[m_voice_select & 0x1f][0x04], + m_sregs[m_voice_select & 0x1f][0x05], + m_sregs[m_voice_select & 0x1f][0x06], + m_sregs[m_voice_select & 0x1f][0x07], + m_sregs[m_voice_select & 0x1f][0x19], + m_sregs[m_voice_select & 0x1f][0x1a], + m_sregs[m_voice_select & 0x1f][0x1b], + m_sregs[m_voice_select & 0x1f][0x1d], + m_sregs[m_voice_select & 0x1f][0x1e], + m_sregs[m_voice_select & 0x1f][0x1f]); } u8 ks0164_device::irqen_76_r() @@ -312,6 +367,64 @@ void ks0164_device::cpu_map(address_map &map) map(0xe000, 0xffff).ram(); } +u16 ks0164_device::uncomp_8_16(u8 value) +{ + int xp = value >> 5; + s16 o = (0x10 | (value & 0xf)) << 10; + o = o >> xp; + if(value & 0x10) + o = -o; + return o; +} + void ks0164_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { + for(int sample = 0; sample != samples; sample++) { + s32 suml = 0, sumr = 0; + for(int voice = 0; voice < 0x20; voice++) { + u16 *regs = m_sregs[voice]; + if(regs[0] & 0x0001) { + u64 current = (u64(regs[1]) << 32) | (regs[2] << 16) | regs[3]; + + if(current & 0xc00000000000) + continue; + + u32 adr = current >> 16; + s16 samp0, samp1; + switch(regs[0] & 0x8400) { + case 0x0000: // 16 bits linear + samp0 = m_mem_cache->read_word(2*adr); + samp1 = m_mem_cache->read_word(2*adr+2); + break; + + case 0x8400: // 8 bits compressed + samp0 = uncomp_8_16(m_mem_cache->read_byte(adr)); + samp1 = uncomp_8_16(m_mem_cache->read_byte(adr+1)); + break; + + default: + logerror("Sample mode %04x\n", regs[0] & 0x8400); + samp0 = samp1 = 0; + break; + } + + s16 samp = samp0 + (((samp1 - samp0) * (current & 0xffff)) >> 16); + current += regs[8]; + u64 end = (u64(regs[0xd]) << 32) | (regs[0xe] << 16) | regs[0xf]; + if(current >= end) { + // Is there a loop enabled flag? + u64 loop = (u64(regs[9]) << 32) | (regs[0xa] << 16) | regs[0xb]; + current = current - end + loop; + } + regs[1] = current >> 32; + regs[2] = current >> 16; + regs[3] = current; + + suml += samp; + sumr += samp; + } + } + outputs[0][sample] = suml >> 5; + outputs[1][sample] = sumr >> 5; + } } diff --git a/src/devices/sound/ks0164.h b/src/devices/sound/ks0164.h index 19167a712d9..f99d4952aab 100644 --- a/src/devices/sound/ks0164.h +++ b/src/devices/sound/ks0164.h @@ -87,6 +87,8 @@ private: void mpu401_w(u8 data); u8 mpu401_istatus_r(); void mpu401_istatus_w(u8 data); + + static inline u16 uncomp_8_16(u8 value); }; DECLARE_DEVICE_TYPE(KS0164, ks0164_device) |