From 4c77c15cceaf0014ab0c69ac937b41c77a180929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Banaan=20Ananas?= Date: Mon, 17 Feb 2014 00:41:33 +0000 Subject: [PATCH] preliminary zsg2 sound now works in taitogn.c, remove the // from //AM_RANGE(0x1fb80000, 0x1fb80003) AM_DEVWRITE16("taito_zoom", taito_zoom_device, reset_control_w, 0xffff0000) --- src/emu/sound/zsg2.c | 164 +++++++++++++++++++++++-------------- src/emu/sound/zsg2.h | 12 +-- src/mame/audio/taito_zm.c | 9 +- src/mame/audio/taito_zm.h | 1 + src/mame/drivers/taitogn.c | 35 +++----- src/mame/drivers/zn.c | 12 +-- 6 files changed, 131 insertions(+), 102 deletions(-) diff --git a/src/emu/sound/zsg2.c b/src/emu/sound/zsg2.c index c62b16b8e7c..5be78b6cbf9 100644 --- a/src/emu/sound/zsg2.c +++ b/src/emu/sound/zsg2.c @@ -42,6 +42,15 @@ To compute the final 16bits value just shift left by (9-s). Yes, that simple. + --------------------------------------------------------- + +Emulation is still preliminary. + +TODO: +- channel volume, 16bits?? need to make a lookup table? +- memory reads out of range sometimes +- a lot of unknowns + */ #include "emu.h" @@ -51,11 +60,6 @@ // device type definition const device_type ZSG2 = &device_creator; - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - //------------------------------------------------- // zsg2_device - constructor //------------------------------------------------- @@ -86,9 +90,50 @@ void zsg2_device::device_start() m_mem_blocks = m_mem_size / 4; m_mem_copy = auto_alloc_array_clear(machine(), UINT32, m_mem_blocks); - m_full_samples = auto_alloc_array_clear(machine(), INT16, m_mem_blocks * 4 + 4); + m_full_samples = auto_alloc_array_clear(machine(), INT16, m_mem_blocks * 4 + 4); // +4 is for empty block + + // register for savestates + save_pointer(NAME(m_mem_copy), m_mem_blocks / sizeof(UINT32)); + save_pointer(NAME(m_full_samples), (m_mem_blocks * 4 + 4) / sizeof(INT16)); + save_item(NAME(m_read_address)); + + for (int ch = 0; ch < 48; ch++) + { + save_item(NAME(m_chan[ch].v), ch); + save_item(NAME(m_chan[ch].is_playing), ch); + save_item(NAME(m_chan[ch].cur_pos), ch); + save_item(NAME(m_chan[ch].step_ptr), ch); + save_item(NAME(m_chan[ch].step), ch); + save_item(NAME(m_chan[ch].start_pos), ch); + save_item(NAME(m_chan[ch].end_pos), ch); + save_item(NAME(m_chan[ch].loop_pos), ch); + save_item(NAME(m_chan[ch].page), ch); + save_item(NAME(m_chan[ch].vol), ch); + } } + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void zsg2_device::device_reset() +{ + m_read_address = 0; + + // stop playing and clear all channels + control_w(4, 0xffff); + control_w(5, 0xffff); + control_w(6, 0xffff); + + for (int ch = 0; ch < 48; ch++) + for (int reg = 0; reg < 0x10; reg++) + chan_w(ch, reg, 0); +} + + +/******************************************************************************/ + UINT32 zsg2_device::read_memory(UINT32 offset) { if (offset >= m_mem_blocks) @@ -155,18 +200,24 @@ void zsg2_device::sound_stream_update(sound_stream &stream, stream_sample_t **in if (m_chan[ch].step_ptr & 0x80000) { 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) { - m_chan[ch].is_playing = false; - //.. - //m_chan[ch].cur_pos = m_chan[ch].loop_pos; + // loop sample + m_chan[ch].cur_pos = m_chan[ch].loop_pos; + if ((m_chan[ch].cur_pos + 1) >= m_chan[ch].end_pos) + { + // end of sample + m_chan[ch].is_playing = false; + continue; + } } m_chan[ch].samples = prepare_samples(m_chan[ch].page | m_chan[ch].cur_pos); } INT16 sample = m_chan[ch].samples[m_chan[ch].step_ptr >> 16 & 3]; - + //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; @@ -178,15 +229,14 @@ void zsg2_device::sound_stream_update(sound_stream &stream, stream_sample_t **in } +/******************************************************************************/ void zsg2_device::chan_w(int ch, int reg, UINT16 data) { - m_chan[ch].v[reg] = data; - switch (reg) { case 0x0: - // lo byte: ? + // lo byte: always 0? // hi byte: start address low m_chan[ch].start_pos = (m_chan[ch].start_pos & 0xff00) | (data >> 8 & 0xff); break; @@ -199,7 +249,7 @@ void zsg2_device::chan_w(int ch, int reg, UINT16 data) break; case 0x4: - // frequency? + // frequency m_chan[ch].step = data; break; @@ -220,27 +270,48 @@ void zsg2_device::chan_w(int ch, int reg, UINT16 data) m_chan[ch].loop_pos = (m_chan[ch].loop_pos & 0x00ff) | (data << 8 & 0xff00); break; + case 0xb: + // always writes 0 + // this register is read-only + break; + + case 0xe: + // channel volume, reg 0xc is also related? + m_chan[ch].vol = data; + break; + default: break; - } + + m_chan[ch].v[reg] = data; } UINT16 zsg2_device::chan_r(int ch, int reg) { + switch (reg) + { + case 0xb: + // ? + return 0; + + default: + break; + } + return m_chan[ch].v[reg]; } - +/******************************************************************************/ void zsg2_device::control_w(int reg, UINT16 data) { - switch(reg) + switch (reg) { case 0x00: case 0x01: case 0x02: { - // key on? + // key on int base = (reg & 3) << 4; for (int i = 0; i < 16; i++) { @@ -251,39 +322,6 @@ void zsg2_device::control_w(int reg, UINT16 data) m_chan[ch].cur_pos = m_chan[ch].start_pos; m_chan[ch].step_ptr = 0; m_chan[ch].samples = prepare_samples(m_chan[ch].page | m_chan[ch].cur_pos); - - - -#if 0 - printf("keyon %02x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", - ch, - m_chan[ch].v[0x0], m_chan[ch].v[0x1], m_chan[ch].v[0x2], m_chan[ch].v[0x3], - m_chan[ch].v[0x4], m_chan[ch].v[0x5], m_chan[ch].v[0x6], m_chan[ch].v[0x7], - m_chan[ch].v[0x8], m_chan[ch].v[0x9], m_chan[ch].v[0xa], m_chan[ch].v[0xb], - m_chan[ch].v[0xc], m_chan[ch].v[0xd], m_chan[ch].v[0xe], m_chan[ch].v[0xf]); - -/* -r 0020 0010 - 0000ee50 00003b94 -r 0020 0014 - 00019be0 000066f8 -r 0020 0018 - 00018eac 000063ab -r 0020 001c - 0000003c 0000000f -keyon 15 - -9400 083b 00 01 start addr 083b94 -0000 0400 02 03 -2cec 04 -1cab 05 ab = loop addr low -66f8 06 end addr -1c63 07 63 = loop addr high -f1a0 0000 0000 0000 f1a0 1b78 089e 1523 - - - -*/ - -#endif - - } } break; @@ -324,25 +362,30 @@ f1a0 0000 0000 0000 f1a0 1b78 089e 1523 UINT16 zsg2_device::control_r(int reg) { - switch(reg) + switch (reg) { case 0x14: - return 0xff00; + // memory bus busy? + // right before reading memory, it polls until low 8 bits are 0 + return 0; case 0x1e: // rom readback word low - if (m_read_address >= m_mem_blocks) return 0; - return m_mem_base[m_read_address] & 0xffff; + return read_memory(m_read_address) & 0xffff; case 0x1f: // rom readback word high - if (m_read_address >= m_mem_blocks) return 0; - return m_mem_base[m_read_address] >> 16; - } + return read_memory(m_read_address) >> 16; - return 0xffff; + default: + break; + } + + return 0; } +/******************************************************************************/ + WRITE16_MEMBER(zsg2_device::write) { // we only support full 16-bit accesses @@ -367,7 +410,6 @@ WRITE16_MEMBER(zsg2_device::write) } } - READ16_MEMBER(zsg2_device::read) { // we only support full 16-bit accesses diff --git a/src/emu/sound/zsg2.h b/src/emu/sound/zsg2.h index 50eed55d0f3..9c8268e75e3 100644 --- a/src/emu/sound/zsg2.h +++ b/src/emu/sound/zsg2.h @@ -39,6 +39,7 @@ public: protected: // device-level overrides virtual void device_start(); + virtual void device_reset(); // sound stream update overrides virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples); @@ -47,13 +48,7 @@ private: // 16 registers per channel, 48 channels struct zchan { - zchan() - { - memset(v, 0, sizeof(UINT16)*16); - } - UINT16 v[16]; - bool is_playing; INT16 *samples; UINT32 cur_pos; @@ -63,6 +58,7 @@ private: UINT32 end_pos; UINT32 loop_pos; UINT32 page; + UINT16 vol; }; zchan m_chan[48]; @@ -79,8 +75,8 @@ private: devcb2_read32 m_ext_read_handler; UINT32 read_memory(UINT32 offset); - void chan_w(int chan, int reg, UINT16 data); - UINT16 chan_r(int chan, int reg); + void chan_w(int ch, int reg, UINT16 data); + UINT16 chan_r(int ch, int reg); void control_w(int reg, UINT16 data); UINT16 control_r(int reg); INT16 *prepare_samples(UINT32 offset); diff --git a/src/mame/audio/taito_zm.c b/src/mame/audio/taito_zm.c index ab0e8c93806..8314dc42490 100644 --- a/src/mame/audio/taito_zm.c +++ b/src/mame/audio/taito_zm.c @@ -43,6 +43,7 @@ const device_type TAITO_ZOOM = &device_creator; taito_zoom_device::taito_zoom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, TAITO_ZOOM, "Taito Zoom Sound System", tag, owner, clock, "taito_zoom", __FILE__), m_soundcpu(*this, ":mn10200"), + m_control(0), m_tms_ctrl(0) { } @@ -56,6 +57,7 @@ void taito_zoom_device::device_start() m_snd_shared_ram = auto_alloc_array_clear(machine(), UINT8, 0x100); // register for savestates + save_item(NAME(m_control)); save_item(NAME(m_tms_ctrl)); save_pointer(NAME(m_snd_shared_ram), 0x100); } @@ -105,7 +107,7 @@ WRITE8_MEMBER(taito_zoom_device::tms_ctrl_w) ADDRESS_MAP_START( taitozoom_mn_map, AS_PROGRAM, 16, driver_device ) AM_RANGE(0x080000, 0x0fffff) AM_ROM AM_REGION("mn10200", 0) - AM_RANGE(0x400000, 0x40ffff) AM_RAM + AM_RANGE(0x400000, 0x41ffff) AM_RAM AM_RANGE(0x800000, 0x8007ff) AM_DEVREADWRITE("zsg2", zsg2_device, read, write) AM_RANGE(0xc00000, 0xc00001) AM_RAM // TMS57002 comms AM_RANGE(0xe00000, 0xe000ff) AM_DEVREADWRITE8("taito_zoom", taito_zoom_device, shared_ram_r, shared_ram_w, 0xffff) // M66220FP for comms with maincpu @@ -136,13 +138,16 @@ READ16_MEMBER(taito_zoom_device::sound_irq_r) WRITE16_MEMBER(taito_zoom_device::global_volume_w) { + // TODO + // m_control d0 selects left/right speaker volume (zsg2+dsp) } WRITE16_MEMBER(taito_zoom_device::reset_control_w) { - // d0: ? (toggles in soundtest) // d2: reset sound cpu? m_soundcpu->set_input_line(INPUT_LINE_RESET, (data & 4) ? CLEAR_LINE : ASSERT_LINE); + + m_control = data; } diff --git a/src/mame/audio/taito_zm.h b/src/mame/audio/taito_zm.h index 36d2f0ef308..bae3aeda5e8 100644 --- a/src/mame/audio/taito_zm.h +++ b/src/mame/audio/taito_zm.h @@ -32,6 +32,7 @@ private: required_device m_soundcpu; // internal state + UINT16 m_control; UINT8 m_tms_ctrl; UINT8* m_snd_shared_ram; }; diff --git a/src/mame/drivers/taitogn.c b/src/mame/drivers/taitogn.c index 81251510536..7c7068e5dca 100644 --- a/src/mame/drivers/taitogn.c +++ b/src/mame/drivers/taitogn.c @@ -403,40 +403,25 @@ private: READ8_MEMBER(taitogn_state::control_r) { - // fprintf(stderr, "gn_r %08x @ %08x (%s)\n", 0x1fb00000+4*offset, mem_mask, machine().describe_context()); return m_control; } WRITE8_MEMBER(taitogn_state::control_w) { // 20 = watchdog - // 04 = select bank - - COMBINE_DATA(&m_control); - m_mb3773->write_line_ck((data & 0x20) >> 5); -#if 0 - if((p ^ control) & ~0x20) - fprintf(stderr, "control = %c%c.%c %c%c%c%c (%s)\n", - control & 0x80 ? '1' : '0', - control & 0x40 ? '1' : '0', - control & 0x10 ? '1' : '0', - control & 0x08 ? '1' : '0', - control & 0x04 ? 'f' : '-', - control & 0x02 ? '1' : '0', - control & 0x01 ? '1' : '0', - machine().describe_context()); -#endif - + // 04 = select bank // According to the rom code, bits 1-0 may be part of the bank // selection too, but they're always 0. - m_flashbank->set_bank(m_control & 4); + m_flashbank->set_bank(data & 4); + + m_control = data; } WRITE16_MEMBER(taitogn_state::control2_w) { - COMBINE_DATA(&m_control2); + m_control2 = data; } READ8_MEMBER(taitogn_state::control3_r) @@ -446,7 +431,7 @@ READ8_MEMBER(taitogn_state::control3_r) WRITE8_MEMBER(taitogn_state::control3_w) { - COMBINE_DATA(&m_control3); + m_control3 = data; } READ16_MEMBER(taitogn_state::gn_1fb70000_r) @@ -494,11 +479,11 @@ READ8_MEMBER(taitogn_state::znsecsel_r) WRITE8_MEMBER(taitogn_state::znsecsel_w) { - COMBINE_DATA( &m_n_znsecsel ); + m_znsec0->select( ( data >> 2 ) & 1 ); + m_znsec1->select( ( data >> 3 ) & 1 ); + m_zndip->select( ( data & 0x8c ) != 0x8c ); - m_znsec0->select( ( m_n_znsecsel >> 2 ) & 1 ); - m_znsec1->select( ( m_n_znsecsel >> 3 ) & 1 ); - m_zndip->select( ( m_n_znsecsel & 0x8c ) != 0x8c ); + m_n_znsecsel = data; } READ8_MEMBER(taitogn_state::boardconfig_r) diff --git a/src/mame/drivers/zn.c b/src/mame/drivers/zn.c index 2b96b165da7..ddd56f505ce 100644 --- a/src/mame/drivers/zn.c +++ b/src/mame/drivers/zn.c @@ -330,13 +330,13 @@ READ8_MEMBER(zn_state::znsecsel_r) WRITE8_MEMBER(zn_state::znsecsel_w) { - COMBINE_DATA( &m_n_znsecsel ); - - m_znsec0->select( ( m_n_znsecsel >> 2 ) & 1 ); - m_znsec1->select( ( m_n_znsecsel >> 3 ) & 1 ); - m_zndip->select( ( m_n_znsecsel & 0x8c ) != 0x8c ); - verboselog(2, "znsecsel_w( %08x, %08x, %08x )\n", offset, data, mem_mask ); + + m_znsec0->select( ( data >> 2 ) & 1 ); + m_znsec1->select( ( data >> 3 ) & 1 ); + m_zndip->select( ( data & 0x8c ) != 0x8c ); + + m_n_znsecsel = data; } READ8_MEMBER(zn_state::boardconfig_r)