diff --git a/src/emu/sound/zsg2.c b/src/emu/sound/zsg2.c index 39ceea22273..0112c82c98b 100644 --- a/src/emu/sound/zsg2.c +++ b/src/emu/sound/zsg2.c @@ -48,8 +48,7 @@ Emulation is still preliminary. TODO: - channel volume, 16bits?? need to make a lookup table? -- how does panning work? it is not simply left/right volume -- (some) samples are in stereo format? +- some samples are in stereo format? - memory reads out of range sometimes - a lot of unknowns @@ -204,7 +203,7 @@ void zsg2_device::sound_stream_update(sound_stream &stream, stream_sample_t **in if (m_chan[ch].step_ptr & 0x40000) { m_chan[ch].step_ptr &= 0xffff; - if (++m_chan[ch].cur_pos > m_chan[ch].end_pos) + if (++m_chan[ch].cur_pos >= m_chan[ch].end_pos) { // loop sample m_chan[ch].cur_pos = m_chan[ch].loop_pos; @@ -223,8 +222,8 @@ void zsg2_device::sound_stream_update(sound_stream &stream, stream_sample_t **in //sample = (sample * (m_chan[ch].vol & 0xffff)) / 0x10000; if (m_chan[ch].vol == 0) sample = 0; // temp hack to prevent stuck notes - mix_l += sample; - mix_r += sample; + mix_l += (sample * m_chan[ch].panl + sample * (0x1f - m_chan[ch].panr)) >> 5; + mix_r += (sample * m_chan[ch].panr + sample * (0x1f - m_chan[ch].panl)) >> 5; } outputs[0][i] = mix_l / 48; @@ -240,7 +239,7 @@ void zsg2_device::chan_w(int ch, int reg, UINT16 data) switch (reg) { case 0x0: - // lo byte: always 0? + // lo byte: unknown, 0 on most games // hi byte: start address low m_chan[ch].start_pos = (m_chan[ch].start_pos & 0xff00) | (data >> 8 & 0xff); break; @@ -252,14 +251,22 @@ void zsg2_device::chan_w(int ch, int reg, UINT16 data) m_chan[ch].page = data << 8 & 0xff0000; break; + case 0x2: + // no function? always 0 + break; + + case 0x3: + // unknown, always 0x0400 + break; + case 0x4: // frequency - m_chan[ch].step = data; + m_chan[ch].step = data + 1; break; case 0x5: // lo byte: loop address low - // hi byte: right(?) panning (high bits always 0) + // hi byte: right panning (high bits always 0) m_chan[ch].loop_pos = (m_chan[ch].loop_pos & 0xff00) | (data & 0xff); m_chan[ch].panr = data >> 8 & 0x1f; break; @@ -271,18 +278,22 @@ void zsg2_device::chan_w(int ch, int reg, UINT16 data) case 0x7: // lo byte: loop address high - // hi byte: left(?) panning (high bits always 0) + // hi byte: left panning (high bits always 0) m_chan[ch].loop_pos = (m_chan[ch].loop_pos & 0x00ff) | (data << 8 & 0xff00); m_chan[ch].panl = data >> 8 & 0x1f; break; + case 0x9: + // no function? always 0 + break; + case 0xb: // always writes 0 // this register is read-only break; case 0xe: - // channel volume, reg 0xc is also related? + // channel volume, reg 0xa/0xc is also related? m_chan[ch].vol = data; break;